Android 获取应用程序';s资源语言
在运行时,是否有可能知道我的应用程序中嵌入了哪些资源语言 i、 e此文件夹的存在:Android 获取应用程序';s资源语言,android,Android,在运行时,是否有可能知道我的应用程序中嵌入了哪些资源语言 i、 e此文件夹的存在: values-en values-de values-fr ... 你在说这个吗 String language = Locale.getDefault().getDisplayLanguage(); 这些语言实际上取决于语言环境,所以您需要从设备获取语言环境,并且可以从语言环境获取显示的语言 Locale myPhoneLocale = Locale.getDefault(); 然后可以调用getDisp
values-en
values-de
values-fr
...
你在说这个吗
String language = Locale.getDefault().getDisplayLanguage();
这些语言实际上取决于语言环境,所以您需要从设备获取语言环境,并且可以从语言环境获取显示的语言
Locale myPhoneLocale = Locale.getDefault();
然后可以调用getDisplayLanguage()以了解显示的是哪种语言 参考:请尝试呼叫: 获取此资产管理器包含数据的区域设置 或者,如果可以使用获取列表,您也可以尝试 返回给定路径上所有资产的字符串数组 你是说:
String[] locales = getAssets().getLocales();
这将使您获得设备所使用的语言。这很复杂,因为即使您有一个名为
values de
的文件夹,也不意味着您在那里有任何资源。如果在values de
中有string.xml
,并不意味着这里有字符串值
价值观:
<resources>
<string name="app_name">LocTest</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
</resources>
LocTest
你好,世界!
设置
de值:
<resources>
<string name="hello_world">Hallo Welt!</string>
</resources>
你好,韦尔特!
您可以测试特定区域设置的资源是否与默认值不同:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Resources r = getResources();
Configuration c = r.getConfiguration();
String[] loc = r.getAssets().getLocales();
for (int i = 0; i < loc.length; i++) {
Log.d("LOCALE", i + ": " + loc[i]);
c.locale = new Locale(loc[i]);
Resources res = new Resources(getAssets(), metrics, c);
String s1 = res.getString(R.string.hello_world);
c.locale = new Locale("");
Resources res2 = new Resources(getAssets(), metrics, c);
String s2 = res2.getString(R.string.hello_world);
if(!s1.equals(s2)){
Log.d("DIFFERENT LOCALE", i + ": "+ s1+" "+s2 +" "+ loc[i]);
}
}
DisplayMetrics=新的DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(度量);
Resources r=getResources();
配置c=r.getConfiguration();
字符串[]loc=r.getAssets().getLocales();
对于(int i=0;i
它有一个错误-您可以检查一个值是否有翻译
上面的脏代码将打印如下内容:
地区(5667):51:en_NZ地区(5667):52:uk_UA地区(5667):53:
nl_BE LOCALE(5667):54:de_de DIFFERENT LOCALE(5667):54:Hallo Welt!
你好,世界!地区(5667):55:ka_GE地区(5667):56:sv_SE
地区(5667):57:bg_-bg地区(5667):58:de_-CH不同
地点(5667):58:你好!你好,世界!德鲁奇地区(5667):59:
fr_CH地区(5667):60:fi_-fi
实际上,AssetManager.getLocales()就是实现这一点的方法。但是,从公共API中,您创建的每个AssetManager的搜索路径中都包含框架资源。。。因此,当您调用AssetManager.getLocales()时,您还将看到作为框架资源一部分的任何区域设置。SDK无法解决这个问题,抱歉。受上述答案的启发,我创建了一个简单的方法,根据提供的翻译获取所有应用程序的语言:
public static Set<String> getAppLanguages( Context ctx, int id ) {
DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
Configuration conf = ctx.getResources().getConfiguration();
Locale originalLocale = conf.locale;
conf.locale = Locale.ENGLISH;
final String reference = new Resources( ctx.getAssets(), dm, conf ).getString( id );
Set<String> result = new HashSet<>();
result.add( Locale.ENGLISH.getLanguage() );
for( String loc : ctx.getAssets().getLocales() ){
if( loc.isEmpty() ) continue;
Locale l = Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH ? new Locale( loc.substring( 0, 2 ) ) : Locale.forLanguageTag( loc );
conf.locale = l;
if( !reference.equals( new Resources( ctx.getAssets(), dm, conf ).getString( id ) ) ) result.add( l.getLanguage() );
}
conf.locale = originalLocale;
return result;
}
publicstaticset-getAppLanguages(Context-ctx,int-id){
DisplayMetrics dm=ctx.getResources().getDisplayMetrics();
配置conf=ctx.getResources().getConfiguration();
Locale originalLocale=conf.Locale;
conf.locale=locale.ENGLISH;
最终字符串引用=新资源(ctx.getAssets(),dm,conf).getString(id);
Set result=new HashSet();
add(Locale.ENGLISH.getLanguage());
对于(字符串loc:ctx.getAssets().getLocales()){
如果(loc.isEmpty())继续;
Locale l=Build.VERSION.SDK_INT对于任何使用Gradle的人,我都是这样做的:它遍历所有strings.xml
,获取目录名并从中计算出区域设置。它将String[]
添加到BuildConfig
中,您可以通过BuildConfig.TRANSLATION\u数组
访问它
task buildTranslationArray << {
def foundLocales = new StringBuilder()
foundLocales.append("new String[]{")
fileTree("src/main/res").visit { FileVisitDetails details ->
if(details.file.path.endsWith("strings.xml")){
def languageCode = details.file.parent.tokenize('/').last().replaceAll('values-','').replaceAll('-r','-')
languageCode = (languageCode == "values") ? "en" : languageCode;
foundLocales.append("\"").append(languageCode).append("\"").append(",")
}
}
foundLocales.append("}")
//Don't forget to remove the trailing comma
def foundLocalesString = foundLocales.toString().replaceAll(',}','}')
android.defaultConfig.buildConfigField "String[]", "TRANSLATION_ARRAY", foundLocalesString
}
preBuild.dependsOn buildTranslationArray
task buildTranslationArray
if(details.file.path.endsWith(“strings.xml”)){
def languageCode=details.file.parent.tokenize('/').last().replaceAll('values-','').replaceAll('-r','-'))
languageCode=(languageCode=“值”)?“en”:languageCode;
foundLocales.append(\).append(语言代码)。append(\).append(,)
}
}
foundLocales.append(“}”)
//别忘了删除后面的逗号
def foundLocaleString=foundLocales.toString().replaceAll(',}','}'))
android.defaultConfig.buildConfigField“String[]”,“TRANSLATION_ARRAY”,FoundLocaleString
}
preBuild.dependsOn buildTranslationArray
因此,在上述任务发生后(在预构建时),BuildConfig.TRANSLATION\u数组
中有您的区域设置列表
我不是Gradle/Groovy专家,所以这肯定会更整洁一些
推理——我在实现pawelzieba的解决方案时遇到了太多问题,我没有可靠的字符串来“比较”,因为翻译是众包的。最简单的方法是查看可用的blah文件夹的值。受代码启发by@Injecteer
我已经做了以下工作:
关于语言清单如果应用程序支持,则有必要传递默认语言,因为无法检测
public static Map<String,String> getAppLanguages(Context context, String appDefaultLang) {
Map<String, String> listAppLocales = new LinkedHashMap<>();
listAppLocales.put("default","Auto");
DisplayMetrics metrics = new DisplayMetrics();
Resources res = context.getResources();
Configuration conf = res.getConfiguration();
String[] listLocates = res.getAssets().getLocales();
for (String locate : listLocates) {
conf.locale = new Locale(locate);
Resources res1 = new Resources(context.getAssets(), metrics, conf);
String s1 = res1.getString(R.string.title_itinerary);
String value = ucfirst(conf.locale.getDisplayName());
conf.locale = new Locale("");
Resources res2 = new Resources(context.getAssets(), metrics, conf);
String s2 = res2.getString(R.string.title_itinerary);
if (!s1.equals(s2)) {
listAppLocales.put(locate, value);
} else if (locate.equals(appDefaultLang)) {
listAppLocales.put(locate, value);
}
}
return listAppLocales;
}
publicstaticmap getAppLanguages(上下文上下文,字符串appDefaultLang){
Map listAppLocales=新建LinkedHashMap();
put(“默认”、“自动”);
DisplayMetrics=新的DisplayMetrics();
Resources res=context.getResources();
Configuration=res.getConfiguration();
字符串[]ListLocations=res.getAssets().getLocales();
for(字符串定位:listLocates){
conf.locale=新的语言环境(locate);
Resources res1=新资源(context.getAssets(),metrics,conf);
strings1=res1.getString(R.String.title\u行程);
字符串值=ucfirst(conf.locale.getDisplayName());
conf.locale=新语言环境(“”);
Resources res2=新资源(context.getAssets(),metrics,conf);
String s2=res2.getString(R.String.title\u行程);
如果(!s1.等于(s2)){
listAppLocales.put(locat
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
BuildConfig.TRANSLATION_ARRAY