回答
AssetManager.getLocales()实际上是做到这一点的方式。但是,从公共API中,您创建的每个AssetManager也都具有包含在其搜索路径中的框架资源...因此,当您调用AssetManager.getLocales()时,您还将看到属于框架资源一部分的任何区域设置。没有办法用SDK解决这个问题,对不起。
你在说什么吗?
String language = Locale.getDefault().getDisplayLanguage();
不,这种方法只是返回默认语言,我想知道我的res文件夹中指定的所有语言 – VinceFR 2012-07-23 10:55:21
getLocales()返回我的设备上可用的语言,而不是我的应用程序。 列表(字符串路径)没有把戏 – VinceFR 2012-07-26 08:19:50
你的意思是:
String[] locales = getAssets().getLocales();
这将让你得到您的设备安装的语言。
我不想拥有我的设备的语言,但我的应用程序有语言 – VinceFR 2012-07-26 08:07:43
这很复杂,因为即使您有一个名为values-de
的文件夹,也并不意味着您在那里有任何资源。如果你有string.xml
values-de
这并不意味着你有字符串值。
值:
<resources>
<string name="app_name">LocTest</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
</resources>
值-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]);
}
}
它有一个错误 - 你可以检查一个值是否有翻译。
上述脏代码将打印类似:
区域设置(5667):51:en_NZ区域设置(5667):52:uk_UA区域设置(5667):53: nl_BE区域设置(5667):54 :de_DE不同的地方(5667):54:Hallo世界! Hello world! de_DE LOCALE(5667):55:ka_GE LOCALE(5667):56:sv_SE LOCALE(5667):57:bg_BG LOCALE(5667):58:de_CH DIFFERENT LOCALE(5667):58:Hallo Welt!你好,世界!将de_CH区域设置(5667):59: fr_CH表示区域设置(5667):60:fi_FI
这应该是一个答案 – injecteer 2015-10-14 15:30:24
通过以上我的答案启发创建了一个简单的方法来获得基于提供的翻译所有应用程序的语言:
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;
}
其中作为id
ARG应该使用它在所有的翻译提供,并包含明确区分的R.string.some_message
文字,像"Do you really want to delete the object?"
也许这将帮助别人......
对于使用摇篮的人,我做到了,就像下面这样遍历所有strings.xml
,抓取目录名称并从那里计算出语言环境。它增加了一个String[]
到BuildConfig
,您可以访问如BuildConfig.TRANSLATION_ARRAY
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
所以发生后,上述任务(上预生成)的BuildConfig.TRANSLATION_ARRAY
有你的语言环境的列表。
我不是Gradle/Groovy的专家,所以这绝对可以有点整洁。
推理 - 我遇到了很多实施pawelzieba解决方案的问题,当翻译被众包时,我没有可靠的字符串来“比较”。最简单的方法是实际查看可用的值-blah文件夹。
通过@的代码启发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;
}
结果是应用程序所支持的语言列表map<key,value>
,第一件事情是,如果你想用它来填充listPreference
的灵感来自正在好转哈克斯之解决方案我创建的东西有点清洁:
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
然后在Java中使用:
BuildConfig.TRANSLATION_ARRAY
这种方法的Advatages:
- 较小的APK - resConfigs将从库切出资源,你不需要(一些有数百)
- 快速 - 无需解析资源配置
- 1. Android Studio:从多语言应用程序资源获取字符串时出错
- 2. 为C#应用程序添加新的语言资源文件
- 3. 从应用程序语言(而不是系统语言)中选择资源
- 4. 在android apk应用程序中添加语言资源
- 5. 用于教授自然语言的程序的资源
- 6. 编程语言设计的好资源?
- 7. 不同的语言资源
- 8. 获取应用程序引擎中已用资源的数量
- 9. GWT应用程序获取“404请求的资源不可用”
- 10. 获取应用程序的可用语言
- 11. 动态获取应用程序的可用语言
- 12. 如何获取iPhone应用程序使用的语言
- 13. 提取应用程序资源
- 14. App Store - 具有多种资源的应用程序的“每种语言”版本
- 15. 防止应用程序从其他应用程序获取资源
- 16. 获取资源的Android应用程序开发NotFoundException
- 17. 如何获取RCP应用程序中的资源对象
- 18. 通过应用程序自动获取cocos2dx的当前资源
- 19. 获取iOS应用程序的“〜/资源库”路径可靠
- 20. 获取Phonegap应用程序的设备语言
- 21. 用户可以从iPhone应用程序获取资源吗?
- 22. .NET MVC应用程序加载错误的语言资源文件
- 23. 使用语言资源编译部署MVC应用程序到Azure错误
- 24. 语言限制资源.resx
- 25. 语言资源包为空
- 26. 使用资源更改WinForm的语言
- 27. 无法从android应用程序获取资源
- 28. 获取应用程序标准资源管理器
- 29. 如何从应用程序资源中获取IconRef
- 30. 无法从应用程序资源中获取图像
只是好奇:但默认情况下,你不知道哪些语言环境,因为你把它们放在应用程序? – 2012-07-25 17:53:32
你是对的!但我创建一个库(所以最终开发人员可以添加语言),我需要以编程方式知道有多少嵌入 – VinceFR 2012-07-26 07:49:11