In many cases, multilingual users set their system language to one language—such as English—but they want to select other languages for specific apps, such as Dutch, Chinese, or Hindi. To help apps provide a better experience for these users, Android 13 introduces the following features for apps that support multiple languages:
System settings that let users select a preferred language for each app in a centralized location.
Your app must declare the
android:localeConfig
attribute in your app's manifest to tell the system that it supports multiple languages. To learn more, see the instructions for creating a resource file and declaring it in your app's manifest file.APIs that let apps set a different language at runtime to use in their user interface.
Apps that use custom in-app language pickers should use these new APIs to ensure that users have a consistent user experience regardless of where they select their language preferences. The new APIs also help you reduce the amount of boilerplate code, they support split APKs, and they support Auto Backup for Apps to store app-level user language settings.
For backward compatibility with previous Android versions, APIs are also available in AndroidX. We recommend using Appcompat 1.6.0-alpha04 or higher.
Apps that do not support multiple languages are not impacted by these changes.
Overview of implementing this feature
The following table shows recommended implementations based on different use cases.
Use case | Recommended implementation |
---|---|
Your app doesn't have an in-app language picker |
|
Your app already has an in-app language picker |
|
System settings for users
Android 13 adds a centralized location in phone settings for setting per-app
language preferences. To ensure your app's languages are configurable in system
settings on devices running Android 13, create a locales_config
XML file and
add it your app's manifest using the android:localeConfig
attribute. Omitting
the android:localeConfig
manifest entry signals that users should not be able
to set your app's language independent of their system language within their
phone settings.
Use android:localeConfig
to add supported languages to phone settings
To add your app's supported languages to a user's phone settings:
Create a file called
res/xml/locales_config.xml
, and specify your app’s languages as follows:<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="ja"/> <locale android:name="fr"/> <locale android:name="en"/> </locale-config>
In the manifest, add a line pointing to this new file:
<manifest ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest>
How users select an app language in system settings
Users can select their preferred language for each app through the new system settings. They can access these settings in two different ways:
Access through the System settings
Settings > System > Languages & Input > App Languages > (select an app)
Access through Apps settings
Settings > Apps > (select an app) > Language
Known issues
There are a few known issues to keep in mind as you test your app.
- If you are using Android Gradle plugin (AGP) version 7.3.0-alpha07 through
7.3.0-beta02 or 7.4.0-alpha01 through 7.4.0-alpha03, you might encounter an
issue that causes resource linking to fail when you declare
android:localeConfig
in your app's manifest file. This issue has been resolved in later versions of the AGP. If you are encountering this issue, use AGP 7.3.0-beta04 or later, AGP 7.4.0-alpha05 or later, or a prior AGP release.
Handle in-app language pickers
For apps that already have an in-app language picker or want to use one, use the new APIs instead of custom app logic to handle setting and getting a user's preferred language for your app.
For backward compatibility with previous Android versions, we strongly recommend using the AndroidX support library when implementing an in-app language picker. However, you can also implement the framework APIs directly if you need to.
Implement using the AndroidX support library
Use the setApplicationLocales()
method in Appcompat 1.6.0-alpha04
or higher.
For example, to set a user's preferred language, you would ask the user to select a locale in the language picker, then set that value in the system:
Kotlin
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags("xx-YY") // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale)
Java
LocaleListCompat appLocale = LocaleListCompat.forLanguageTags("xx-YY"); // Call this on the main thread as it may require Activity.restart() AppCompatDelegate.setApplicationLocales(appLocale);
Support Android 12 and lower
To support for devices running Android 12 (API level 32) and lower, tell
AndroidX to handle locale storage by setting an autoStoreLocales
value to
true
and android:enabled
to false
in the manifest entry for your app's
AppLocalesMetadataHolderService
service, as shown in the following code
snippet:
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
Note that setting an autoStoreLocales
value to true
causes a blocking read
on the main thread and might cause a
StrictMode
diskRead
and
diskWrite
violation if you are logging thread violations. See
AppCompatDelegate.setApplicationLocales()
for more information.
Custom storage handling
Omitting the manifest entry or setting autoStoreLocales
to false
signals
that you are handling your own storage. In this case, you must provide the
stored locales before onCreate
in the activity lifecycle and gate calls to
AppCompatDelegate.setApplicationLocales()
in Android 12 (API level 32) or
lower.
If your app has a custom locale storage location, we recommend using a one-time
handoff between your custom locale storage solution and autoStoreLocales
so
users continue to enjoy your app in the language they prefer. This is especially
applicable in cases when your app is first run after a device has upgraded to
Android 13. In this case, you can provide pre-existing user-requested locales by
retrieving the locales from your custom storage and passing the locales into
AppCompatDelegate.setApplicationLocales()
.
Implement using the Android framework APIs
While we strongly recommend that you use the AndroidX support library to
implement in-app language pickers, you can also use the
setApplicationLocales()
and getApplicationLocales()
methods in the Android framework for devices running Android 13.
For example, to set a user's preferred language, you would ask the user to select a locale in the language picker, then set that value in the system:
// 1. Inside an activity, in-app language picker gets an input locale "xx-YY"
// 2. App calls the API to set its locale
mContext.getSystemService(LocaleManager.class
).setApplicationLocales(newLocaleList(Locale.forLanguageTag("xx-YY")));
// 3. The system updates the locale and restarts the app, including any configuration updates
// 4. The app is now displayed in "xx-YY" language
To get a user's current preferred language to display in the language picker, your app can get the value back from the system:
// 1. App calls the API to get the preferred locale
LocaleList currentAppLocales =
mContext.getSystemService(LocaleManager.class).getApplicationLocales();
// 2. App uses the returned LocaleList to display languages to the user
Additional best practices
Take note of the following best practices.
Consider language when invoking an intent in another app
Language-focused intents might allow you to specify the language you want the
invoked app to be in. One example is the Speech Recognizer API’s
EXTRA_LANGUAGE
feature.
Consider the Accept-Language header for Chrome Custom tab
Consider adding the Accept-Language Header
through the Browser.EXTRA_HEADERS
to open a web page in your app's language when invoking a Chrome Custom tab.