How do “Locale.getDefault()” and “getResources().getConfiguration().getLocales().get(0)” work exactly?

My app (Java 11, min: API 29, target: API 30 = Android 11) currently supports two languages: German (default) & English

The “build.gradle(Module:app)” file contains resConfigs("de", "en") and there are two strings.xml files with the translations.

According to the official docs, Locale.getDefault() should return:

the current value of the default locale for the specified Category for this instance of the Java Virtual Machine.

If I understand this correctly, then this is the Locale currently being used by the app.

The docs for getLocales() only say:

Get the locale list. This is the preferred way for getting the locales (instead of using the direct accessor to locale, which would only provide the primary locale).

… but according to multiple threads, this function is also supposed to return the Locale that’s currently being used by the app. I want to know which language this is, so I did some testing with the following print:

Log.d(TAG,"1="+Locale.getDefault()+", 2="+getResources().getConfiguration().getLocales().get(0));
  • Set the emulator to “English (US)” -> English is chosen correctly, prints “1=en_US, 2=en_US”
  • German (CH) -> German is chosen correctly, prints “1=de_CH, 2=de_CH”
  • German + English (US) -> German is chosen correctly, prints “1=de_CH, 2=de_CH”
  • Danish + German (CH) -> German is chosen correctly, prints “1=de_CH, 2=de_CH”
  • Danish + English (US) -> English is chosen correctly, prints “1=en_US, 2=en_US”
  • Danish + Italian -> German is chosen correctly, prints “1=da_DK, 2=da_DK”
  • Italian + Spanish -> German is chosen correctly, prints “1=in_IT, 2=in_IT”

It looks like they are either set to the language that is both supported by the app and chosen in Android’s settings by the user OR the first language chosen by the user if none of them are supported by the app.

My app’s got a spinner that changes the language. Calling e.g. Locale.setDefault(Locale.English) switches everything to English but if I switch from the first activity to the second, then this value is reset. E.g.:

German + English (US) -> German is chosen automatically (prints “1=de_CH, 2=de_CH”) -> switch to English -> UI elements switch too -> switch activity -> prints “1=de_CH, 2=en” in onCreateView, while all the UI elements are in English; with Danish + Italian it prints “1=da_DK, 2=en”

I’m aware that getResources().getConfiguration().getLocales().get(0) requires a call to onConfigurationChanged to change, while Locale.setDefault() applies the change instantly but why did the latter reset all of a sudden? Why did I get the results I got during my tests, instead of the Locale currently in use? How do you get a reliable result for the Locale the app actually uses (it can’t just be this, right?)?

Or better: How do both of these functions actually work? Are they simply buggy?

The docs don’t mention any of this but only how the Locale is chosen on app start (here) and the latest changes to the language preferences only apply to Android 13+.

  • after u make language switch …. did u make a full restart for the app ?

    – 

  • @Mohmmaed-Amleh No, that’s not necessary if you do it in onConfigurationChanged. Any idea why what’s happening is happening?

    – 




Leave a Comment