Finally, some localization updates for Android! Android 13 was released in the summer of 2022, and it has a ton of cool new stuff to work with. Today, I’ll share a small piece I’m passionate about - per-app language settings.

Up until now, the active locale of a device was based solely on the device’s system-wide language settings. Supporting any kind of in-app option required building custom language pickers and managing user settings in our app’s preference cache. This has been somewhat improved with per-app language settings, and I’m hoping we continue to see more support in this area. Localization can play a huge part in product acceptance and market expansion, and the less custom stuff we have to build, the less we have to maintain down the line.

I had planned to write this post as more of an intro to configuring per-app language settings because I find the documentation to be a bit chaotic and hard to follow. But as I was gathering materials for that work, I found that the Android devs beat me to it! Not only have they blogged about it, but they’ve also added more info to the developer docs since the initial release - though I have to say, it’s still hard to follow with all the warnings and in-page links and… maybe just start with the blog post that I linked below.

So instead of that post, what I’ll do for you instead is give a short overview of the API updates - what’s provided and what isn’t - share some sample code, and talk a bit about what I think is missing from all this.

If you want to get more familiar with the new feature before reading on, here are the Android developer resources I recommend you look at:

And here are two great videos sadly buried in the docs - one an overview of the per-app setting, and one a great intro into internationalization on Android.

API Feature Overview

What’s improved?

Application language settings can now be system-managed

This is big! After configuring per-app language settings, we can delegate managing a user’s language settings to Android’s system processes and stop worrying about managing language preferences ourselves. Unless you have special needs, you can throw out your custom-built system - you don’t need to maintain it anymore! Let the App Info page handle it for you.

Android per app language settings

Android now provides purpose-built classes to manage active locales

Static functions provided by the AppCompatDelegate and LocaleManagerCompat classes are now available to get, set, and store application locales, and between the two of them, you get access to all application- and system-level locale information you need. No more messing about with Java’s Locale class and forgetting to also update your active resource configuration - keep things simple with Android’s API.

All of this is backward compatible

If you use all the new classes and rely on the system to do the work, you can configure applications built for older versions of Android to also have most of the functionality of these features. Users won’t get the language selection option on your App Info page (oh well), but because you’ve configured the storage in your Manifest, you can use AppCompatDelegate to set and get locale info your users may have selected through a language picker or some other method.

This is particularly nice because it shows that Android is working to provide the per-app language experience to as many people as it can. I’m not sure how far back the compatibility goes, but I expect this could impact a lot of projects.

What’s missing?

There’s still no in-app language picker

I sort of understand this one. Every app is different, and there’s no good way to provide a language picker that everyone will want to use. We’d probably still see a bunch of custom implementations anyway. Honestly, I’m not convinced in-app language changes are something Android ever really intended to support - at least not without jumping through hoops. Even official Android documentation pushed developers to use the system-level locale and do full restarts to reload with a new language. And the per-app settings are great, but they’re still managed at a system level. I don’t know if a language picker is on their radar. You’ll still be building your own, thank you very much.

All this being said, you can absolutely navigate from your app directly to its system-managed language settings! It may not provide an ideal user experience, but the option is there. LinkedIn did it, which lines up with their track record on UX… but sometimes laziness can be good. I kind of like it.

LinkedIne Android per app language flow

Configuration is pretty clean… but also there’s potentially a lot of it

Initial configuration is not too bad - add the correct Compat libraries, create a locale XML file, update your manifest for backward compatibility, and add new API code to your app where needed. But how do you populate a language picker? None of those files generate in-app files for you to use, and I haven’t yet seen a function to retrieve all available app locales at runtime. You’ll need at least one other file for your language list, and maybe you’ll need duplicate lists to display language names for different locales. You get it all in and publish.

Now, you want to add a language to your application. Good luck remember all the files you need to add it to. It may not sound like much, but it’s like updating a single string in ten places. Will you remember to update them all? And will you notice if you don’t? Again, I love this feature. I’m just not a fan of how clunky it may end up being to use.

(I’ve built a little plugin that may help with some aspects of this, though! More on that in my next post.)

This feature feels incomplete

The documentation for the feature was crammed onto a single page, it’s filled with caveats about confusing known issues, and there don’t seem to be any finalized, stable libraries for us to import into our projects with confidence. I mean, who wants to use the questionable Appcompat 1.6.0-beta01 or higher? Is it safe? Are we going to have to update when something stable arrives? No idea.

Listen - I’m still excited about this feature, and you should be, too! But I’m also keeping an eye out for updates.

Sample Project

As promised, I have a sample project for you! I updated my l10n_samples project with support for per-app language preferences, and I added a page with a super simple language picker. You can change the language to watch the app update in real time. Bonus - since the new locale changer updates the whole app, you no longer need to update the system language to test out the other samples. (Knew I’d get that in there eventually!)

Gif showing sample locale changer

Thanks for reading, and I hope you got something useful out of my love for internationalization. I would love to answer questions and chat about this new feature, so please comment with anything you have, and we can nerd out about all this together. Happy coding!