
Em muitos casos, usuários multilíngues definem um idioma para o sistema, por exemplo, o inglês, mas querem selecionar outros idiomas para apps específicos, como holandês, chinês ou hindi. Para melhorar a experiência dos usuários nos apps que oferecem suporte a vários idiomas, o Android 13 introduz os recursos abaixo:
Configurações do sistema: um local centralizado em que os usuários podem selecionar um idioma preferido para cada app.
Para informar ao sistema que ele oferece suporte para vários idiomas, o app precisa declarar o atributo
android:localeConfig
no manifesto. Para saber mais, consulte as instruções sobre como criar um arquivo de recursos e o declarar no arquivo de manifesto do app.Outras APIs: essas APIs públicas, como os métodos
setApplicationLocales()
egetApplicationLocales()
emLocaleManager
, permitem que os apps definam um idioma diferente daquele usado pelo sistema no momento da execução.Essas APIs são sincronizadas automaticamente com as configurações do sistema. Os apps que usam essas APIs para criar seletores de idioma personalizados garantem que os usuários tenham uma experiência consistente, independente do local em que escolherem as preferências de idioma. As APIs públicas também ajudam a reduzir o código boilerplate e oferecem suporte para APKs divididos e para Backup automático de apps, permitindo que os aplicativos armazenem as configurações de idioma do usuário.
Para oferecer compatibilidade com versões anteriores do Android, APIs equivalentes também estão disponíveis no AndroidX. Recomendamos o uso do Appcompat 1.6.0-beta01 ou versões mais recentes.
Visão geral da implementação desse recurso
A tabela a seguir mostra as implementações recomendadas de acordo com os diferentes casos de uso.
Caso de uso | Implementação recomendada |
---|---|
O app não tem um seletor de idioma |
|
O app já tem um seletor de idioma |
|
Configurações do sistema para usuários
Do Android 13 em diante, há um local centralizado nas configurações do sistema
para definir a seleção de idioma por app. Para garantir que os idiomas
do app possam ser definidos nas configurações do sistema em dispositivos com o Android 13 ou
versão mais recente, crie um arquivo XML locales_config
e adicione-o ao manifesto do app usando
o atributo android:localeConfig
. A omissão da entrada
de manifesto android:localeConfig
indica que os usuários não vão ter a opção de definir idiomas
diferentes para o app e para o sistema.
Usar android:localeConfig
para adicionar os idiomas disponíveis às configurações do sistema
Para adicionar os idiomas disponíveis nas configurações do sistema, siga estas etapas:
Crie um arquivo chamado
res/xml/locales_config.xml
e especifique os idiomas do app, incluindo a localidade substituta final, que é a especificada emres/values/strings.xml
.Para formar os nomes de localidade, combine o código do idioma com o script opcional e os códigos de região, separando cada um com um traço.
Idioma: use o código ISO 639-1 de duas ou três letras.
Script (opcional): use o código ISO 15924.
Região (opcional): use o código ISO 3166-1-alpha-2 de duas letras ou o código UN_M.49 de três dígitos.
Consulte o formato sugerido no exemplo de arquivo
locale_config.xml
para conferir uma lista das localidades mais usadas.Por exemplo, formate o arquivo
locales_config.xml
desta forma em um app com suporte para os seguintes idiomas:- Inglês (Estados Unidos) como localidade substituta final
- Inglês (Reino Unido)
- Francês
- Japonês
- Chinês (simplificado, Macau)
- Chinês (tradicional, Macau)
<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale android:name="en"/> <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>
No manifesto do app, adicione uma linha que leve a esse novo arquivo:
<manifest> ... <application ... android:localeConfig="@xml/locales_config"> </application> </manifest>
Especificar idiomas com suporte no Gradle
Especifique os mesmos idiomas usando a propriedade resourceConfigurations
no arquivo build.gradle
do módulo do app:
android {
...
defaultConfig {
resourceConfigurations += ["en", "en-rGB", "fr", "ja", "b+zh+Hans+MO", "b+zh+Hant+MO"]
}
}
Quando a propriedade resourceConfigurations
está presente, o sistema de build inclui apenas
recursos de idioma no APK para esses idiomas especificados, impedindo
que strings traduzidas sejam incluídas de outras bibliotecas com suporte
a idiomas que o app não usa. Para
mais informações, consulte
Especificar os idiomas com suporte no app.
Como os usuários selecionam um idioma para o app nas configurações do sistema
Com as configurações do sistema, os usuários podem selecionar um idioma preferido para cada app. Os usuários podem acessar essas configurações de duas maneiras:
Acessar as configurações do sistema
Configurações > Sistema > Idioma e entrada > Idiomas do app > (selecionar um app)
Acessar as configurações dos apps
Configurações > Apps > (selecionar um app) > Idioma
Problemas conhecidos
Confira alguns problemas conhecidos dos testes de app:
- Se você está usando o Plug-in do Android para Gradle (AGP) versão 7.3.0-alpha07 a
7.3.0-beta02 ou 7.4.0-alpha01 a 7.4.0-alpha03, pode ter um
problema que faz a vinculação de recursos falhar se
android:localeConfig
for declarado no arquivo de manifesto do app. Esse problema foi resolvido em versões mais recentes do AGP e SDK do Android. Se você tiver esse problema, use o AGP 7.3.0-beta04 ou mais recente ou o AGP 7.4.0-alpha05 ou mais recente, com o SDK versão 33 (compileSdk = 33
).
Processar seletores de idioma no app
Para apps que já têm um seletor de idioma integrado ou que querem usar um, utilize as APIs públicas em vez da lógica personalizada do app para descobrir e configurar o idioma preferido do usuário. Se o seletor de idioma no app depender das APIs públicas, as configurações do sistema do dispositivo vão ser atualizadas automaticamente para corresponder ao idioma que o usuário selecionar no app.
Para oferecer compatibilidade com versões anteriores do Android, recomendamos o uso da Biblioteca de Suporte do AndroidX ao implementar um seletor de idioma no app. Também é possível implementar as APIs de framework diretamente, se necessário.
Implementar usando a Biblioteca de Suporte do AndroidX
Use os métodos setApplicationLocales()
e getApplicationLocales()
na Appcompat 1.6.0-beta01
ou versões mais recentes.
Por exemplo, para definir o idioma de preferência de um usuário, peça para que ele selecione uma localidade no seletor de idioma e defina esse valor no 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);
Tenha em mente que chamar setApplicationLocales()
recria a Activity
, a menos que
o app processe mudanças de configuração
de localidade por conta própria.
Use AppCompatDelegate.getApplicationLocales()
para extrair a localidade de preferência do usuário. A localidade do app pode ser escolhida pelo usuário nas configurações do sistema ou no seletor de idioma do app.
Suporte para Android 12 e versões anteriores
Para oferecer suporte para dispositivos com o Android 12 (API de nível 32) e versões anteriores, instrua o
AndroidX a processar o armazenamento da localidade. Para isso, defina o valor autoStoreLocales
como
true
e android:enabled
como false
na entrada do serviço
AppLocalesMetadataHolderService
no manifesto do app, conforme mostrado no snippet de código
a seguir:
<application
...
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
Definir o valor autoStoreLocales
como true
causa uma leitura de método de bloqueio
na linha de execução principal e pode causar uma violação
StrictMode
, diskRead
e diskWrite
se o app estiver registrando violações de linha de execução. Consulte
AppCompatDelegate.setApplicationLocales()
se quiser mais informações.
Processar armazenamento personalizado
Omitir a entrada de manifesto ou definir autoStoreLocales
como false
indica que o app processa um armazenamento próprio. Nesse caso, é necessário informar as
localidades armazenadas antes de onCreate
no ciclo de vida da atividade e bloquear chamadas para
AppCompatDelegate.setApplicationLocales()
no Android 12 (API de nível 32) ou
versões anteriores.
Se o app tiver um local de armazenamento de localidades personalizado, recomendamos usar uma transferência
única entre a solução de armazenamento de localidades personalizada e autoStoreLocales
, para que
os usuários possam continuar a usar o app no idioma que preferirem. Isso vale principalmente
para os casos em que o app é executado pela primeira vez depois que o dispositivo foi atualizado para o
Android 13. Nesse caso, as localidades já solicitadas pelo usuário podem ser extraídas
do armazenamento personalizado e transmitidas para
AppCompatDelegate.setApplicationLocales()
.
Implementar usando as APIs do framework do Android
Embora seja altamente recomendável usar a Biblioteca de Suporte do AndroidX para
implementar seletores de idioma no app, também é possível usar os métodos
setApplicationLocales()
e getApplicationLocales()
no framework do Android para dispositivos com o Android 13.
Por exemplo, para definir o idioma de preferência de um usuário, peça para que ele selecione uma localidade no seletor de idioma e defina esse valor no 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 o idioma preferido de um usuário apareça no seletor de idioma, o app pode extrair o valor do 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áticas recomendadas adicionais
Confira as práticas recomendadas a seguir.
Considerar o idioma ao invocar uma intent em outro app
Intents de idioma podem permitir especificar o idioma em que você quer
exibir o app invocado. Um exemplo é o recurso
EXTRA_LANGUAGE
da API Speech Recognizer.
Usar o cabeçalho Accept-Language para guias personalizadas do Chrome
Adicione o cabeçalho Accept-Language (link em inglês)
usando Browser.EXTRA_HEADERS
para abrir uma página da Web no mesmo idioma do app ao invocar uma guia personalizada do Chrome.
Se você remover a seleção de idioma por app nas configurações do sistema, defina a localidade do app como a mesma do sistema
Caso a seleção de idioma do app seja removida das configurações do sistema, excluindo
android:localeConfig
e AndroidManifest.xml
, os usuários não poderão
redefinir o idioma do app para o padrão do sistema com facilidade.
Por isso, ao remover android:localeConfig
, use
LocaleListCompat.getEmptyLocaleList()
ou
LocaleList.getEmptyLocaleList()
para definir a
localidade do app como a mesma do sistema,
conforme apresentado no snippet de código a seguir:
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());
Outros recursos (em inglês)
Consulte nossos exemplos de código, artigos do blog e vídeos para mais informações.
- Blog Seleção de idioma por app (parte 1)
- Blog Seleção de idioma por app (parte 2)
- Apps de exemplo
- Vídeo sobre como criar para um mundo multilíngue
Exemplo de arquivo locale_config.xml
Por padrão, o sistema Android inclui traduções no Android Open
Source Project (AOSP) para um conjunto padrão das localidades mais usadas.
O exemplo de arquivo locale_config.xml
incluído nesta seção mostra o
formato sugerido para cada uma dessas localidades. Use esse exemplo como referência quando for
criar seu arquivo locale_config.xml
para o conjunto de idiomas
com suporte no seu 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="en-XA"/> <!-- English (Pseudo-Accents) -->
<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="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="my-MM"/> <!-- Burmese (Myanmar) -->
<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="tl"/> <!-- Filipino -->
<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-CN"/> <!-- Chinese (Simplified) -->
<locale android:name="zh-HK"/> <!-- Chinese (Hong Kong) -->
<locale android:name="zh-TW"/> <!-- Chinese (Traditional) -->
<locale android:name="zu"/> <!-- Zulu -->
</locale-config>