Gotchas in Per-App Language Preferences and Android Locale
These are not the droids you are looking for
Android has a curious way of handling locale.
With the introduction of per-app language preferences, things have gotten even more complicated.
This article won’t go deep into explaining the nooks and crannies of localization. Better blog posts (and the actual Android documentation) exist for that.
Theory is boring enough. Let’s look at a real-world example.
Configuration
Limit language resources.
The resource folders should look something like this:
Let’s experiment
- Android 11
Default resource configuration is used. (es-ES is not supported)
Locale.getDefault()
returns the system language.
Enhance
Add an additional system language: en-AU
.
Since en-AU
is supported, Locale.getDefault()
will coincide with the current resource configuration.
Setting locale with per-app language preferences
First, use the compat
method:
Let’s stop and consider what should be expected:
it
resource configuration is supported in thebuild.gradle
file.- It should be used since it is a fallback for
it-IT
. - Remember, we are on Android 11 (per-app languages are supported via system settings Android 13 onwards, not before).
What about Android 13+?
Same setup as above.
Set it-IT
via AppCompatDelete.setApplicationLocales
.
Locale.getDefault
does follow the application locale now, unlike API <13.
To recap
- Consider carefully what would work best for you when using
Accept-Language
headers (or anything where uniform localization might be desired). - In-app language pickers can be implemented with the AndroidX support library for backward compatibility with all Android versions. A welcome addition, but it adds overhead to an already convoluted problem.
- Behaviour can differ depending on API version, system locale, and per-app language preferences.
What if?
One could piggyback on Android’s resource resolution mechanism instead.
Language/region can be declared arbitrarily as strings in the respective strings.xml
files for each configuration.
This might introduce other complications, though. The app locale is now “tied” to resources.
What region would one set in the en
folder anyway? How many resource configurations should the app support now? Is a region even needed?
Depending on how complex your use case is, this simple thing could be enough.
Gotchas with AndroidX support library
AppCompatDelegate.getApplicationLocales()
will return nothing (empty list) if no app locale has been set manually.- Since this method is reaching for activity behind the scenes to resolve locale, it should only be called after
Activity#onCreate
. For instance, calling this atApplication#onCreate
will always return nothing.
I hope you found this somewhat useful. Thanks for reading.