回答
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