En muchos casos, los usuarios multilingües configuran un idioma para su sistema, como el inglés, pero desean seleccionar otros para apps específicas, como el chino, el hindi o el holandés. Con el fin de ayudar a que las apps brinden una mejor experiencia para estos usuarios, Android 13 presenta las siguientes funciones en las apps que admiten varios idiomas:
Configuración del sistema: Una ubicación centralizada en la que los usuarios pueden seleccionar un idioma preferido para cada app.
Puedes configurar tu app para que genere automáticamente los archivos necesarios para admitir las preferencias de idioma de la app y mostrarlos en la configuración del sistema. Si quieres obtener más información, consulta las instrucciones para habilitar la compatibilidad automática de idioma de las apps.
APIs adicionales: Estas APIs públicas, al igual que los métodos
setApplicationLocales()
ygetApplicationLocales()
enLocaleManager
, permiten que las apps configuren un idioma diferente del idioma del sistema en el tiempo de ejecución.Estas APIs se sincronizan automáticamente con la configuración del sistema. Por lo tanto, las apps que las usan para crear selectores de idioma personalizados integrados en la app garantizarán que los usuarios tengan una experiencia del usuario coherente, sin importar dónde seleccionen sus preferencias de idioma. Las APIs públicas también ayudan a reducir la cantidad de código estándar, admiten APKs divididos y copias de seguridad automáticas para apps con el objetivo de almacenar los parámetros de configuración de idiomas del usuario en el nivel de app.
Para ofrecer retrocompatibilidad con versiones anteriores de Android, las APIs equivalentes también están disponibles en AndroidX. Sin embargo, las APIs retrocompatibles funcionan con el contexto AppCompatActivity, no el contexto de la aplicación, para Android 12 (nivel de API 32) y versiones anteriores. Accede a las APIs retrocompatibles con Appcompat 1.6.0 o versiones posteriores.
Descripción general de la implementación de esta función
En la siguiente tabla, se muestran implementaciones recomendadas, según diferentes casos de uso.
Caso de uso | Implementación recomendada |
---|---|
Tu app no tiene un selector de idioma integrado |
|
Tu app ya incluye un selector de idioma integrado |
|
Configuración del sistema para usuarios
A partir de Android 13, el sistema operativo incluye una ubicación centralizada en la configuración del sistema para preferencias de idioma de las apps. Para asegurarte de que se puedan configurar los idiomas en los parámetros de configuración del sistema en dispositivos que ejecutan Android 13 o versiones posteriores, habilita la compatibilidad automática de idioma de las apps (recomendado) o configura la compatibilidad de forma manual.
Cómo habilitar la compatibilidad automática de idioma de las apps
A partir de Android Studio Giraffe y AGP 8.1, puedes configurar tu app para que admita automáticamente las preferencias de idioma de las apps. En función de los recursos de tu proyecto, AGP genera el archivo LocaleConfig
y le agrega una referencia en el archivo de manifiesto final, por lo que ya no tienes que hacerlo de forma manual. AGP usa los recursos de las carpetas res
de los módulos de tu app y las dependencias de módulos de biblioteca para determinar las configuraciones regionales que se incluirán en el archivo LocaleConfig
. Esto significa que, si agregas recursos para un idioma nuevo a tu app, no tendrás que preocuparte por actualizar el archivo LocaleConfig
.
Ten en cuenta que la función automática de idioma de las apps admite apps que ejecutan Android 13 (nivel de API 33) o versiones posteriores. Para usar la función, debes establecer compileSdkVersion
en 33 o un valor superior. Para configurar las preferencias de idioma de las apps en versiones anteriores de Android, debes usar las APIs y los selectores de idioma integrados en la app.
Para habilitar la compatibilidad automática de idioma de las apps, sigue estos pasos:
- Para activar la función, usa la configuración
generateLocaleConfig
en el bloqueandroidResources {}
del archivobuild.gradle.kts
a nivel del módulo (archivobuild.gradle
si usas Groovy). La función está desactivada de forma predeterminada.Kotlin
android { androidResources { generateLocaleConfig = true } }
Groovy
android { androidResources { generateLocaleConfig true } }
- Especifica una configuración regional predeterminada:
- En la carpeta
res
del módulo de la app, crea un archivo nuevo llamadoresources.properties
. En el archivo
resources.properties
, establece la configuración regional predeterminada con la etiquetaunqualifiedResLocale
. Para dar formato a los nombres de configuración regional, consulta Cómo formar nombres de configuración regional.
- En la carpeta
AGP agrega esta configuración regional predeterminada y todas las configuraciones regionales alternativas que especificaste, con directorios values-*
en la carpeta res
, al archivo LocaleConfig
generado automáticamente.
Cómo formar nombres de configuración regional
Para formar nombres de configuración regional, combina el código de idioma con la secuencia de comandos opcional y los códigos regionales, y separa cada uno con un guion:
- Idioma: Usa el código ISO 639-1 de dos o tres letras.
- Secuencia de comandos (opcional): Usa el código ISO 15924.
- Región (opcional): Usa el código ISO 3166-1-alpha-2 de dos letras o el código UN_M.49 de tres dígitos.
Por ejemplo, si tu configuración regional predeterminada es Inglés (Estados Unidos):
unqualifiedResLocale=en-US
Usa android:localeConfig
para agregar los idiomas compatibles a la configuración del sistema
Puedes configurar la app de forma manual para asegurarte de que los idiomas se puedan establecer en la configuración del sistema en dispositivos que ejecutan Android 13 o versiones posteriores. Para ello, crea un archivo en formato XML locales_config
y agrégalo al manifiesto de tu app con el atributo android:localeConfig
. Si omites los indicadores de entrada del manifiesto android:localeConfig
, los usuarios no podrán configurar un idioma de tu app diferente del idioma del sistema en la configuración del sistema.
Para agregar de forma manual los idiomas compatibles de la app a la configuración del sistema del usuario, haz lo siguiente:
Crea un archivo con el nombre
res/xml/locales_config.xml
y especifica los idiomas de tu app, incluida la configuración regional de resguardo final, que es la configuración regional especificada enres/values/strings.xml
.Consulta Cómo formar nombres de configuración regional para conocer los requisitos de formato. Consulta también el archivo
locale_config.xml
de muestra para obtener una lista de las configuraciones regionales más usadas.Por ejemplo, da formato al archivo
locales_config.xml
de esta manera para una app que admite los siguientes idiomas:- Inglés (Estados Unidos) como la última configuración regional de resguardo
- Inglés (Reino Unido)
- Francés
- Japonés
- Chino (simplificado, Macao)
- Chino (tradicional, Macao)
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="en-US"/> <locale android:name="en-GB"/> <locale android:name="fr"/> <locale android:name="ja"/> <locale android:name="zh-Hans-MO"/> <locale android:name="zh-Hant-MO"/> </locale-config>
En el manifiesto, agrega una línea que dirija a este archivo nuevo:
<manifest> ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest>
Puedes actualizar de forma dinámica el localeConfig
de tu app con LocaleManager.setOverrideLocaleConfig
para personalizar el conjunto de idiomas que se muestra en la lista de idiomas por app en la Configuración de Android. Esto te permite
personalizar la lista de idiomas por región, ejecutar experimentos A/B y proporcionar
configuraciones regionales si tu app usa envíos de localización del servidor, como se muestra en el
siguiente ejemplo:
Kotlin
//For setOverrideLocaleConfig val localeManager = applicationContext .getSystemService(LocaleManager::class.java) localeManager.overrideLocaleConfig = LocaleConfig( LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG") ) //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig val overrideLocaleConfig = localeManager.overrideLocaleConfig // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales val supportedLocales = overrideLocaleConfig.supportedLocales()
Java
//For setOverrideLocaleConfig mContext.getSystemService(LocaleManager.class).setOverrideLocaleConfig(new LocaleConfig(LocaleList.forLanguageTags("en-US,ja-JP,zh-Hans-SG"))); //For getOverrideLocaleConfig // The app calls the API to get the override LocaleConfig LocaleConfig overrideLocaleConfig = mContext.getSystemService(LocaleManager.class).getOverrideLocaleConfig(); // If the returned overrideLocaleConfig isn't equal to NULL, then the app calls the API to get the supported Locales LocaleList supportedLocales = overrideLocaleConfig.getSupportedLocales();
Además, los IME ahora pueden usar
LocaleManager.getApplicationLocales
saber el idioma de la IU de la app actual para actualizar el idioma del teclado como
mostrado:
Kotlin
val currentAppLocales: LocaleList = applicationContext.getSystemService(LocaleManager::class.java).getApplicationLocales(appPackageName)
Java
LocaleList currentAppLocales = mContext.getSystemService(LocaleManager.class).getApplicationLocales(appPackageName);
Especifica los idiomas compatibles en Gradle
Si aún no está presente, especifica los mismos idiomas con la propiedad resourceConfigurations
en el archivo build.gradle
a nivel de módulo de tu app:
android {
...
defaultConfig {
resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
}
}
Cuando la propiedad resourceConfigurations
está presente, el sistema de compilación solo incluye recursos de idiomas en el APK para los idiomas que se especifican, lo que evita que se incluyan strings traducidas de otras bibliotecas de idiomas que tu app podría no admitir. Para obtener más información, consulta Cómo especificar los idiomas que admite tu app.
Cómo los usuarios seleccionan el idioma de una app en la configuración del sistema
Los usuarios pueden seleccionar el idioma de su preferencia para cada app con la configuración del sistema. Pueden acceder a esta configuración de dos maneras diferentes:
Acceder a través de la configuración del sistema
Configuración > Sistema > Idiomas y entradas > Idiomas de las apps > (selecciona una app)
Acceder a través de la configuración de Apps
Configuración > Apps > (selecciona una app) > Idioma
Control de los selectores de idiomas integrados en la app
En el caso de las apps que ya tienen un selector de idioma integrado o que quieren usar uno, usa las APIs públicas en lugar de una lógica de app personalizada para controlar la configuración y obtener el idioma preferido del usuario para tu app. Si usas las APIs públicas para el selector de idioma en tu app, la configuración de sistema del dispositivo se actualiza automáticamente para coincidir con el idioma que seleccione el usuario a través de la experiencia en la app.
Para ofrecer retrocompatibilidad con versiones anteriores de Android, recomendamos que uses la biblioteca de compatibilidad de AndroidX cuando implementes un selector de idioma integrado en la app. Sin embargo, también puedes implementar las APIs del framework directamente si es necesario.
Implementación con la biblioteca de compatibilidad de AndroidX
Usa los métodos setApplicationLocales()
y getApplicationLocales()
en Appcompat 1.6.0 o versiones posteriores. Ten en cuenta que las APIs retrocompatibles funcionan con el contexto AppCompatActivity, no el contexto de la aplicación, para Android 12 (nivel de API 32) y versiones anteriores.
Por ejemplo, para configurar el idioma de preferencia de un usuario, se le solicita seleccionar una configuración regional en el selector de idioma y establecer ese valor en el sistema:
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);
Ten en cuenta que, cuando se llama a setApplicationLocales()
, se recrea tu Activity
, a menos que tu app controle los cambios de configuración regional por su cuenta.
Usa AppCompatDelegate.getApplicationLocales()
para recuperar la configuración regional preferida del usuario. Es posible que el usuario haya seleccionado la configuración regional de la app desde la configuración del sistema o desde el selector de idioma de la app.
Compatibilidad con Android 12 y versiones anteriores
Para admitir dispositivos que ejecutan Android 12 (nivel de API 32) y versiones anteriores, indícale a AndroidX que controle el almacenamiento de la configuración regional mediante la configuración de un valor autoStoreLocales
en true
y android:enabled
en false
en la entrada de manifiesto del servicio AppLocalesMetadataHolderService
de la app, como se muestra en el siguiente fragmento de código:
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
Ten en cuenta que establecer un valor autoStoreLocales
en true
provoca un bloqueo de lectura en el subproceso principal y puede causar un incumplimiento de StrictMode
diskRead
y diskWrite
si registras incumplimientos de subprocesos. Consulta AppCompatDelegate.setApplicationLocales()
para obtener más información.
Control de almacenamiento personalizado
Omitir la entrada del manifiesto o la configuración de autoStoreLocales
en false
indica que controlas tu propio almacenamiento. En este caso, debes proporcionar los parámetros de configuración regional almacenados antes de onCreate
en el ciclo de vida de la actividad y las llamadas de puerta a AppCompatDelegate.setApplicationLocales()
en Android 12 (nivel de API 32) o versiones anteriores.
Si tu app tiene una ubicación de almacenamiento de configuración regional personalizada, se recomienda usar una transferencia única entre la solución de almacenamiento de configuración regional personalizada y autoStoreLocales
, para que los usuarios continúen disfrutando de la app en el idioma que prefieran. Esto se aplica especialmente cuando la app se ejecuta por primera vez después de que un dispositivo se actualizó a Android 13. En este caso, puedes proporcionar parámetros preexistentes de configuración regional que solicitó el usuario. Para ello, debes recuperar estos parámetros de tu almacenamiento personalizado y pasarlos a AppCompatDelegate.setApplicationLocales()
.
Implementación con las APIs del framework de Android
Si bien te recomendamos que uses la biblioteca de compatibilidad de AndroidX para implementar selectores de idiomas integrados en la app, también puedes usar los métodos setApplicationLocales()
y getApplicationLocales()
en el framework de Android para dispositivos que ejecutan Android 13.
Por ejemplo, para configurar el idioma de preferencia de un usuario, se le solicita seleccionar una configuración regional en el selector de idioma y establecer ese valor en el sistema:
// 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(new LocaleList(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
Para que el idioma actual de preferencia de un usuario se muestre en el selector de idioma, tu app puede recuperar el valor del sistema:
// 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
Prácticas recomendadas adicionales
Toma nota de las siguientes prácticas recomendadas.
Ten en cuenta el idioma cuando invoques un intent en otra app
Es posible que los intents centrados en el idioma te permitan especificar el idioma en el que deseas que esté la app invocada. Un ejemplo es la función EXTRA_LANGUAGE
de la API de Speech Recognizer.
Ten en cuenta el encabezado Accept-Language para la pestaña personalizada de Chrome
Te recomendamos que agregues el encabezado Accept-Language a través de Browser.EXTRA_HEADERS
para abrir una página web en el idioma de tu app cuando invoques una pestaña personalizada de Chrome.
Si quitas las preferencias de idioma de las apps en la configuración del sistema, restablece la configuración regional de tu app a la del sistema.
Si quitas las preferencias de idioma de la app de la configuración del sistema (es decir, si quitas android:localeConfig
del archivo AndroidManifest.xml
de tu app), los usuarios no podrán restablecer fácilmente el idioma de la app a la configuración predeterminada del sistema.
Por este motivo, si quitas android:localeConfig
, considera restablecer la configuración regional de la app a la configuración regional del sistema con LocaleListCompat.getEmptyLocaleList()
o LocaleList.getEmptyLocaleList()
, como se ve en el siguiente fragmento de código:
Kotlin
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ) // Or use the Framework APIs for Android 13 and above to reset to the system locale val context = LocalContext.current context.getSystemService(LocaleManager::class.java) .applicationLocales = LocaleList.getEmptyLocaleList()
Java
// Use the AndroidX APIs to reset to the system locale for backward and forward compatibility AppCompatDelegate.setApplicationLocales( LocaleListCompat.getEmptyLocaleList() ); // Or use the Framework APIs for Android 13 and above to reset to the system locale mContext.getSystemService(LocaleManager.class) .setApplicationLocales(LocaleList.getEmptyLocaleList());
Recursos adicionales
Consulta nuestras muestras de código, artículos de blog y videos para obtener información adicional.
- Blog Preferencias de idioma de las apps parte 1
- Blog Preferencias de idioma de las apps parte 2
- Aplicaciones de ejemplo
- Video Cómo crear contenido para un mundo multilingüe
Ejemplo de archivo locale_config.xml
De forma predeterminada, Android incluye traducciones a nivel del sistema en el Proyecto de código abierto de Android (AOSP) para un conjunto estándar de las configuraciones regionales de uso general.
El archivo locale_config.xml
de muestra que se incluye en esta sección muestra el formato sugerido para cada una de estas configuraciones regionales. Consulta este archivo de muestra para ayudarte a crear tu propio archivo locale_config.xml
para el conjunto de lenguajes que admite tu app.
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="af"/> <!-- Afrikaans -->
<locale android:name="am"/> <!-- Amharic -->
<locale android:name="ar"/> <!-- Arabic -->
<locale android:name="as"/> <!-- Assamese -->
<locale android:name="az"/> <!-- Azerbaijani -->
<locale android:name="be"/> <!-- Belarusian -->
<locale android:name="bg"/> <!-- Bulgarian -->
<locale android:name="bn"/> <!-- Bengali -->
<locale android:name="bs"/> <!-- Bosnian -->
<locale android:name="ca"/> <!-- Catalan -->
<locale android:name="cs"/> <!-- Czech -->
<locale android:name="da"/> <!-- Danish -->
<locale android:name="de"/> <!-- German -->
<locale android:name="el"/> <!-- Greek -->
<locale android:name="en-AU"/> <!-- English (Australia) -->
<locale android:name="en-CA"/> <!-- English (Canada) -->
<locale android:name="en-GB"/> <!-- English (United Kingdom) -->
<locale android:name="en-IN"/> <!-- English (India) -->
<locale android:name="en-US"/> <!-- English (United States) -->
<locale android:name="es"/> <!-- Spanish (Spain) -->
<locale android:name="es-US"/> <!-- Spanish (United States) -->
<locale android:name="et"/> <!-- Estonian -->
<locale android:name="eu"/> <!-- Basque -->
<locale android:name="fa"/> <!-- Farsi -->
<locale android:name="fi"/> <!-- Finnish -->
<locale android:name="fil"/> <!-- Filipino -->
<locale android:name="fr"/> <!-- French (France) -->
<locale android:name="fr-CA"/> <!-- French (Canada) -->
<locale android:name="gl"/> <!-- Galician -->
<locale android:name="gu"/> <!-- Gujarati -->
<locale android:name="hi"/> <!-- Hindi -->
<locale android:name="hr"/> <!-- Croatian -->
<locale android:name="hu"/> <!-- Hungarian -->
<locale android:name="hy"/> <!-- Armenian -->
<locale android:name="in"/> <!-- Indonesian -->
<locale android:name="is"/> <!-- Icelandic -->
<locale android:name="it"/> <!-- Italian -->
<locale android:name="iw"/> <!-- Hebrew -->
<locale android:name="ja"/> <!-- Japanese -->
<locale android:name="ka"/> <!-- Georgian -->
<locale android:name="kk"/> <!-- Kazakh -->
<locale android:name="km"/> <!-- Khmer -->
<locale android:name="kn"/> <!-- Kannada -->
<locale android:name="ko"/> <!-- Korean -->
<locale android:name="ky"/> <!-- Kyrgyz -->
<locale android:name="lo"/> <!-- Lao -->
<locale android:name="lt"/> <!-- Lithuanian -->
<locale android:name="lv"/> <!-- Latvian -->
<locale android:name="mk"/> <!-- Macedonian -->
<locale android:name="ml"/> <!-- Malayalam -->
<locale android:name="mn"/> <!-- Mongolian -->
<locale android:name="mr"/> <!-- Marathi -->
<locale android:name="ms"/> <!-- Malay -->
<locale android:name="my"/> <!-- Burmese -->
<locale android:name="nb"/> <!-- Norwegian -->
<locale android:name="ne"/> <!-- Nepali -->
<locale android:name="nl"/> <!-- Dutch -->
<locale android:name="or"/> <!-- Odia -->
<locale android:name="pa"/> <!-- Punjabi -->
<locale android:name="pl"/> <!-- Polish -->
<locale android:name="pt-BR"/> <!-- Portuguese (Brazil) -->
<locale android:name="pt-PT"/> <!-- Portuguese (Portugal) -->
<locale android:name="ro"/> <!-- Romanian -->
<locale android:name="ru"/> <!-- Russian -->
<locale android:name="si"/> <!-- Sinhala -->
<locale android:name="sk"/> <!-- Slovak -->
<locale android:name="sl"/> <!-- Slovenian -->
<locale android:name="sq"/> <!-- Albanian -->
<locale android:name="sr"/> <!-- Serbian (Cyrillic) -->
<locale android:name="sr-Latn"/> <!-- Serbian (Latin) -->
<locale android:name="sv"/> <!-- Swedish -->
<locale android:name="sw"/> <!-- Swahili -->
<locale android:name="ta"/> <!-- Tamil -->
<locale android:name="te"/> <!-- Telugu -->
<locale android:name="th"/> <!-- Thai -->
<locale android:name="tr"/> <!-- Turkish -->
<locale android:name="uk"/> <!-- Ukrainian -->
<locale android:name="ur"/> <!-- Urdu -->
<locale android:name="uz"/> <!-- Uzbek -->
<locale android:name="vi"/> <!-- Vietnamese -->
<locale android:name="zh-Hans"/> <!-- Chinese (Simplified) -->
<locale android:name="zh-Hant"/> <!-- Chinese (Traditional) -->
<locale android:name="zu"/> <!-- Zulu -->
</locale-config>