Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 获取应用程序';s资源语言_Android - Fatal编程技术网

Android 获取应用程序';s资源语言

Android 获取应用程序';s资源语言,android,Android,在运行时,是否有可能知道我的应用程序中嵌入了哪些资源语言 i、 e此文件夹的存在: values-en values-de values-fr ... 你在说这个吗 String language = Locale.getDefault().getDisplayLanguage(); 这些语言实际上取决于语言环境,所以您需要从设备获取语言环境,并且可以从语言环境获取显示的语言 Locale myPhoneLocale = Locale.getDefault(); 然后可以调用getDisp

在运行时,是否有可能知道我的应用程序中嵌入了哪些资源语言

i、 e此文件夹的存在:

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