How to get language (locale) currently Android app displays?
Asked Answered
O

6

35

How to get know language (locale) currently Android app uses to display texts to user?

I know I can use Locale.getDefault() to get default OS locale. But it may differ from locale used by app to display text and other resources, if this locale isn't supported by app.


I need to determine language (locale) displayed by the app, thus the app can pass language to the server, so it can localise returned results.

Otherworld answered 31/12, 2011 at 20:44 Comment(0)
O
52

My own solution is to add to strings.xml key-value pair locale=<locale code>, thus context.getResources().getString(R.string.locale) will return locale code specific for used locale.

Otherworld answered 31/12, 2011 at 23:39 Comment(4)
I guess this solution was supposed to be the part of your question.Wig
@YaqubAhmad I came to this solution later. But I am still waiting for possible better solution.Otherworld
I like this solution because then I am guaranteed to get the locale code only if my translation resources are being used. And that is the only time I want it. Otherwise, I might get dates in one language and other string resources in another language if I made some sort of mistake with getting the locale.Dittography
10 years passed, and this is still the only way to get the needed locale.Subternatural
F
33

It's on your app configuration, so you can get it with :

getResources().getConfiguration().locale

this is different from

Locale.getDefault()

and shows the Locale that the app uses which can be different.

It can be different because the developer can change it by updating the app configuration, check : Resources.updateConfiguration

Ferdinana answered 21/9, 2012 at 12:13 Comment(5)
The docs for the 1st fn you list says "Current user preference for the locale, corresponding to locale resource qualifier". If this is 'current user preference' then how is it different from the 2nd fn. Either way, which function of Locale class does one call to get the locale code String (equivalent to resource extension) that can be passed back to server (as in original question)?Thimbu
This answer mentions the correct way of getting the Locale (first line of code). But it's wrong that there is a difference: Locale.getDefault() is equivalent to the first example. If you want to get the language code, you have to call getLanguage().Ananias
Unfortunately, this doesn't work like I need. If set System language, e.g., for Dansk (Danish), getResources().getConfiguration().locale returns da_DK, while display English strings (from values/strings.xml).Otherworld
getResources().getConfiguration().locale.getLanguage(); is the correct wayAirplane
Neither works properly: My app supports English (default) and German and I set the emulator's languages to 1. Danish and 2. German (CH). My app then correctly chooses German but Locale.getDefault() says "de_CH", instead of the device's language (=Danish). getResources().getConfiguration().getLocales().get(0) (doesn't matter if with or without getLanguage()) correctly prints "German", however if the device uses a language/languages the app doesn't support (e.g. Danish+Italian), then both that one and Locale.getDefault() return the device's language, instead of the app's.Manpower
S
5

The following code works for me:

@TargetApi(Build.VERSION_CODES.M)
private String getCurrentDefaultLocaleStr(Context context) {
    Locale locale = context.getResources().getConfiguration().locale;
    return locale.getDefault().toString();
}

Note: There is a slight change on how you should get locale on Build.VERSION_CODES.N. For N and above, the code should look like the code block below; however, I just do it for M and below like in the above code block and it is compatible for N and above also.

    // Build.VERSION_CODES.N
    Locale locale = context.getResources().getConfiguration().getLocales().get(0);

I got the following on the national languages I support:

English:             en 
Traditional Chinese: zh_TW_#Hant 
Simplified Chinese:  zh_CN_#Hans
Spanish:             es_ES
French:              fr_FR
Japanese:            ja_JP
German:              de_DE

There is a list of methods that give the same locale information in different formats:

locale.getDefault().getCountry();
locale.getDefault().getISO3Language();
locale.getDefault().getISO3Country();
locale.getDefault().getDisplayCountry();
locale.getDefault().getDisplayName();
locale.getDefault().getDisplayLanguage();
locale.getDefault().getLanguage();
locale.getDefault().toString();

Slothful answered 17/8, 2017 at 18:47 Comment(1)
There's no non-static getDefault() method on LocaleArraignment
I
1

You can use the code below. For example, the functions presented below may be placed inside the class extended the Application class.

public class MyApplication extends Application {
    ...
    public static String APP_LANG;
    private Context ctx = getBaseContext();
    private Resources res = ctx.getResources();
    public SharedPreferences settingPrefs;
    ...

    public void restoreAppLanguage(){
    /**
    *Use this method to store the app language with other preferences.
    *This makes it possible to use the language set before, at any time, whenever 
    *the app will started.
    */
        settingPrefs = getSharedPreferences("ConfigData", MODE_PRIVATE);
        String lang = settingPrefs.getString("AppLanguage", "");
        if(!settingPrefs.getAll().isEmpty() && lang.length() == 2){
            Locale myLocale;
            myLocale = new Locale(lang);
            Locale.setDefault(myLocale);
            Configuration config = new Configuration();
            config.locale = myLocale;
            res.updateConfiguration( config, res.getDisplayMetrics() );
        }
    }

    public void storeAppLanguage(int lang) {
    /**
    *Store app language on demand
    */
        settingPrefs = getSharedPreferences("ConfigData", MODE_PRIVATE);
        Editor ed = settingPrefs.edit();

        Locale myLocale;
        myLocale = new Locale(lang);
        Locale.setDefault(myLocale);
        Configuration config = new Configuration();
        config.locale = myLocale;
        res.updateConfiguration( config, res.getDisplayMetrics() );
        ed.putString("AppLanguage", lang);

        ed.commit();
    }

    public void setAppLanguage(String lang){
    /**
    *Use this method together with getAppLanguage() to set and then restore
    *language, whereever you need, for example, the specifically localized
    *resources.
    */
        Locale myLocale;
        myLocale = new Locale(lang);
        Locale.setDefault(myLocale);
        Configuration config = new Configuration();
        config.locale = myLocale;
        res.updateConfiguration( config, res.getDisplayMetrics() );
    }

    public void getAppLanguage(){
    /**
    *Use this method to obtain the current app language name
    */
        settingPrefs = getSharedPreferences("ConfigData",MODE_PRIVATE);
        String lang = settingPrefs.getString("AppLanguage", "");
        if(!settingPrefs.getAll().isEmpty() && lang.length() == 2){
            APP_LANG = lang;
        }
        else APP_LANG = Locale.getDefault().getLanguage();
    }
}

And then wherever in the main code we can write:

public class MainActivity extends ActionBarActivity {
    ...
    MyApplication app;
    ... 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        app = (MyApplication)getApplicationContext();
        ...
        if(settingPrefs.getAll().isEmpty()){
            //Create language preference if it is not
            app.storeAppLanguage(Locale.getDefault().getLanguage());
        }

        //Restore previously used language
        app.restoreAppLanguage();
        ...
    }
    ...
    void SomethingToDo(){
        String lang = "en"; //"fr", "de", "es", "it", "ru" etc.
        ...
        app.getAppLanguage();
        app.setAppLanguage(lang);
        ...
        //do anything
        ...
        app.setAppLanguage(app.APP_LANG);
    }
    ...
}

In your case, you, shortly, may use getAppLanguage() and then check the public variable APP_LANG to obtain what language is currently used.

Idoux answered 24/4, 2015 at 11:55 Comment(0)
V
1

In Kotlin, you can add the following extension function to your project:

fun Context.getCurrentLocale(): Locale {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
        this.resources.configuration.locales.get(0);
    } else{
        this.resources.configuration.locale;
    }
}

And use it without any warnings:

val locale = applicationContext.getCurrentLocale()

Vastitude answered 20/8, 2021 at 10:1 Comment(0)
S
0
 public boolean CheckLocale(Context context, String app_language) {
        Locale myLocale = new Locale(app_language);
        Resources res = context.getResources();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        if(res.getConfiguration().locale==myLocale)
            return true;
        else 

         return false;

    }

Use this method.

Scream answered 10/5, 2017 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.