是否有可能在运行时知道我的应用程序中嵌入了哪些资源语言?
即存在这个文件夹:
values-en
values-de
values-fr
...
Run Code Online (Sandbox Code Playgroud)
paw*_*eba 13
它很复杂,因为即使你有一个名为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>
Run Code Online (Sandbox Code Playgroud)
值-DE:
<resources>
<string name="hello_world">Hallo Welt!</string>
</resources>
Run Code Online (Sandbox Code Playgroud)
您可以测试特定区域设置的资源是否与默认值不同:
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]);
}
}
Run Code Online (Sandbox Code Playgroud)
它有一个错误 - 您可以检查一个值是否有翻译.
上面的脏代码将打印如下:
LOCALE(5667):51:en_NZ LOCALE(5667):52:uk_UA LOCALE(5667):53:nl_BE LOCALE(5667):54:de_DE不同地方(5667):54:Hallo Welt!你好,世界!de_DE LOCALE(5667):55:ka_GE LOCALE(5667):56:sv_SE LOCALE(5667):57:bg_BG LOCALE(5667):58:de_CH不同地方(5667):58:Hallo Welt!你好,世界!de_CH LOCALE(5667):59:fr_CH LOCALE(5667):60:fi_FI
hac*_*bod 10
AssetManager.getLocales()实际上就是这样做的方法.但是,从公共API开始,您创建的每个AssetManager都会在其搜索路径中包含框架资源...因此,当您调用AssetManager.getLocales()时,您还将看到属于框架资源的任何区域设置.抱歉,无法通过SDK解决这个问题.
对于任何使用 Gradle 的人,我都是这样做的,它遍历 all 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
Run Code Online (Sandbox Code Playgroud)
因此,在上述任务发生后(在预构建时),就会BuildConfig.TRANSLATION_ARRAY有您的语言环境列表。
我不是 Gradle/Groovy 专家,所以这绝对可以更简洁一些。
推理 - 我在实施 pawelzieba 的解决方案时遇到了太多问题,我没有可靠的字符串来“比较”,因为翻译是众包的。最简单的方法是实际查看可用的 values-blah 文件夹。
在Mendhak的解决方案的启发下,我创造了一些更清洁的东西:
defaultConfig {
....
def locales = ["en", "it", "pl", "fr", "es", "de", "ru"]
buildConfigField "String[]", "TRANSLATION_ARRAY", "new String[]{\""+locales.join("\",\"")+"\"}"
resConfigs locales
}
Run Code Online (Sandbox Code Playgroud)
然后在Java中使用:
BuildConfig.TRANSLATION_ARRAY
Run Code Online (Sandbox Code Playgroud)
这种方法的优点:
| 归档时间: |
|
| 查看次数: |
6378 次 |
| 最近记录: |