get the application's resources languages

后端 未结 11 1060
庸人自扰
庸人自扰 2020-12-02 23:30

Is it possible, at runtime, to know which resources languages are embedded in my app?

i.e the presence of this folders:

values-en
values-de
values-fr         


        
相关标签:
11条回答
  • 2020-12-03 00:09

    Inspired by the answers above I created a simple method to get all app's languages based on provided translations:

    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; 
    }
    

    where as id arg should be used a R.string.some_message which is provided in all translations and contains clearly distinguishable text, like "Do you really want to delete the object?"

    Maybe it would help someone...

    0 讨论(0)
  • 2020-12-03 00:12

    AssetManager.getLocales() is actually the way to do this. However, from the public API every AssetManager you create also has the framework resources included in its search path... so when you call AssetManager.getLocales() you will also see any locales that are part of the framework resources. There is no way to get around this with the SDK, sorry.

    0 讨论(0)
  • 2020-12-03 00:13

    Inspired with the code by@Injecteer I have done the following:

    for the list of languages ​​that the app supports , it is necessary to pass the default language , since it is not possible to detect

    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;
    }
    

    The result is a list map<key,value>of languages ​​supported by the application, the first thing is for if you want to use to populate a listPreference

    0 讨论(0)
  • 2020-12-03 00:14

    LocaleList or LocaleListCompat are one of the ways you could get the languages supported by your application.

    LocaleList was introduced in API 24.

    The thing to consider when using LocaleListCompat is that for API < 24 only the first language tag will be used.

    0 讨论(0)
  • 2020-12-03 00:15

    these res-lang actually depends on Locales, so you need to get locale from device and you can get which language is getting shown from locale..

    Locale myPhoneLocale = Locale.getDefault();
    

    You can then call getDisplayLanguage() to know which language is getting shown.

    Reference : Locale

    0 讨论(0)
  • 2020-12-03 00:17

    It's complicated because even if you have a folder named values-de it doesn't mean you have any resources there. If you have string.xml in values-de it doesn't mean you have string value there.

    values:

    <resources>
        <string name="app_name">LocTest</string>
        <string name="hello_world">Hello world!</string>
        <string name="menu_settings">Settings</string>
    </resources>
    

    values-de:

    <resources>
        <string name="hello_world">Hallo Welt!</string>
    </resources>
    

    You can test if a resource for a specific locale is different than the default:

    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]);
        }
    }
    

    It has one fault - you can check one value whether it has translation.

    The dirty code above will print something like:

    LOCALE(5667): 51: en_NZ LOCALE(5667): 52: uk_UA LOCALE(5667): 53: nl_BE LOCALE(5667): 54: de_DE DIFFERENT LOCALE(5667): 54: Hallo Welt! 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! Hello world! de_CH LOCALE(5667): 59: fr_CH LOCALE(5667): 60: fi_FI

    0 讨论(0)
提交回复
热议问题