ChatGPT解决这个技术问题 Extra ChatGPT

Android get current Locale, not default

How do I get the user's current Locale in Android?

I can get the default one, but this may not be the current one correct?

Basically I want the two letter language code from the current locale. Not the default one. There is no Locale.current()

default() is a pretty safe bet, just don't use it for processing (like the docs say).
@A--C use it for processing?
Yeah, see what the docs say: some locales will use ',' as the decimal point and '.' for digit grouping. so stuff like parseInt() may fail. Note that they still recommend using default(), but not for stuff that can break code.

J
JDJ

The default Locale is constructed statically at runtime for your application process from the system property settings, so it will represent the Locale selected on that device when the application was launched. Typically, this is fine, but it does mean that if the user changes their Locale in settings after your application process is running, the value of getDefaultLocale() probably will not be immediately updated.

If you need to trap events like this for some reason in your application, you might instead try obtaining the Locale available from the resource Configuration object, i.e.

Locale current = getResources().getConfiguration().locale;

You may find that this value is updated more quickly after a settings change if that is necessary for your application.


Did anyone check that the default Locale isn't changed in app when you change it in system? I think it's one of those "configuration changes" which make activities destroyed and recreated
I tested it, outputting both while I kept on changing locale; result is, the output is the same. So Locale.getDefault() can be used safely as it gets immediately updated. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
This has been deprecated in the Configuration class, see the latest docs for this advice: locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor.
why don't they just add a getFirstLocale() method to avoid that weird getLocales().get(0)?
What if you want to support older and newer versions of api?
e
ericn

Android N (Api level 24) update (no warnings):

   Locale getCurrentLocale(Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            return context.getResources().getConfiguration().getLocales().get(0);
        } else{
            //noinspection deprecation
            return context.getResources().getConfiguration().locale;
        }
    }

Is there something in the support library to avoid the if-else?
@TargetApi(Build.VERSION_CODES.N) is not needed in your code if you include the if and fallback code
This may not work if the user has multiple languages installed. You should use LocaleList.getDefault().get(0); as this will return the Locales sorted by the preferred language.
@FedericoPonzi @for3st I found this in ConfigurationCompat, as ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
Why not just use Locale.getDefault()?
E
ElegyD

If you are using the Android Support Library you can use ConfigurationCompat instead of @Makalele's method to get rid of deprecation warnings:

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

or in Kotlin:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]

If you don't have any context you can also do ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
@QuentinG. Yes, but better to use the Application context in this case.
So to be clear, this won't return the default locale but the user preferred locale?
k
kabuko

From getDefault's documentation:

Returns the user's preferred locale. This may have been overridden for this process with setDefault(Locale).

Also from the Locale docs:

The default locale is appropriate for tasks that involve presenting data to the user.

Seems like you should just use it.


this answer is wrong, got a default locale but if user changed it on fly it show wrong. next answer is correct
agreed, wrong answer. In my case, I was looking for a way to not have to use getResources(), which means I need a context. My problem was a helper class that didn't have a context, but guess I'll have to pass it on in. If you have an app that lets people change their locale and have the views' strings, number formats etc change, then you need to use Devunwired's response
Work for me. If I set a breakpoint at Locale.setDefault(), it get's called when I change the device language at least back to Android 5.0 (that's as far as I tested)
А
Александр Остапюк

All answers above - do not work. So I will put here a function that works on 4 and 9 android

private String getCurrentLanguage(){
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
      return LocaleList.getDefault().get(0).getLanguage();
   } else{
      return Locale.getDefault().getLanguage();
   }
}

One of the few answers that returns the user's preferred language direction at the device level. You can also use LocaleListCompat.getDefault() if you use AndroidX.
C
Community

As per official documentation ConfigurationCompat is deprecated in support libraries

You can consider using

LocaleListCompat.getDefault()[0].toLanguageTag() 0th position will be user preferred locale

To get Default locale at 0th position would be LocaleListCompat.getAdjustedDefault()


Yes but hasn't it been replaced with the androidx ConfigurationCompat version, see developer.android.com/reference/androidx/core/os/…
Correct, maybe it's only mentioned because of androidx migration
A
Alif Hasnain

As for now, we can use ConfigurationCompat class to avoid warnings and unnecessary boilerplates.

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

f
fvaldivia

I´ve used this:

String currentLanguage = Locale.getDefault().getDisplayLanguage();
if (currentLanguage.toLowerCase().contains("en")) {
   //do something
}

Note: ISO 639 is not a stable standard— some languages' codes have changed. Locale's constructor recognizes both the new and the old codes for the languages whose codes have changed, but this function always returns the old code. If you want to check for a specific language whose code has changed, don't do if (locale.getLanguage().equals("he")) // BAD! Instead, do if (locale.getLanguage().equals(new Locale("he").getLanguage()))
Please see this link for more information about what @Ari described: developer.android.com/reference/java/util/Locale#getLanguage()
f
farhad.kargaran

I used this simple code:

if(getResources().getConfiguration().locale.getLanguage().equalsIgnoreCase("en"))
{
   //do something
}