O Android obtém o local atual, não o padrão

300

Como obtenho a localidade atual do usuário no Android?

Posso obter o padrão, mas este pode não ser o atual correto?

Basicamente, quero o código de idioma de duas letras do local atual. Não é o padrão. Não háLocale.current()

CQM
fonte
default()é uma aposta bastante segura, mas não a utilize para processamento (como dizem os documentos).
A - C
@ A - C usá-lo para processamento?
CQM
Sim, veja o que dizem os documentos : alguns códigos de idioma usarão ',' como ponto decimal e '.' para agrupamento de dígitos. então coisas como parseInt () podem falhar. Observe que eles ainda recomendam o uso default(), mas não para coisas que podem quebrar o código.
A - C

Respostas:

487

O padrão Localeé construído estaticamente em tempo de execução para o processo do aplicativo a partir das configurações de propriedade do sistema, portanto, ele representará o Localeselecionado nesse dispositivo quando o aplicativo foi iniciado . Normalmente, isso é bom, mas significa que, se o usuário alterar suas Localeconfigurações após a execução do processo do aplicativo, o valor de getDefaultLocale()provavelmente não será atualizado imediatamente.

Se você precisar interceptar eventos como esse por algum motivo em seu aplicativo, tente obter o Localedisponível no Configurationobjeto de recurso , por exemplo

Locale current = getResources().getConfiguration().locale;

Você pode achar que esse valor é atualizado mais rapidamente após uma alteração nas configurações, se necessário para o seu aplicativo.

Devunwired
fonte
1
Alguém verificou se o código de idioma padrão não é alterado no aplicativo quando você o altera no sistema? Eu acho que é uma daquelas "alterações de configuração" que fazem atividades destruído e recriado
Michał K
11
Eu testei, produzindo os dois enquanto continuava alterando a localidade; O resultado é que a saída é a mesma. Portanto, Locale.getDefault () pode ser usado com segurança, pois é atualizado imediatamente. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio
58
Isso foi preterido na classe Configuração, consulte os documentos mais recentes para este conselho:locale This field was deprecated in API level 24. Do not set or read this directly. Use getLocales() and setLocales(LocaleList). If only the primary locale is needed, getLocales().get(0) is now the preferred accessor.
MrBigglesworth
7
por que eles simplesmente não adicionam um método getFirstLocale () para evitar esse estranho getLocales (). get (0)?
user3290180
1
E se você deseja oferecer suporte a versões mais antigas e mais recentes da API?
Ivan
179

Atualização do Android N (Api nível 24) (sem avisos):

   Locale getCurrentLocale(Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            return context.getResources().getConfiguration().getLocales().get(0);
        } else{
            //noinspection deprecation
            return context.getResources().getConfiguration().locale;
        }
    }
Makalele
fonte
6
Existe algo na biblioteca de suporte para evitar o if-else?
Federico Ponzi
8
@TargetApi (Build.VERSION_CODES.N) não é necessário em seu código se você incluir o caso e fallback código
Patrick Favre
@FedericoPonzi no ResourceCompat parece não ter um método para localidade a partir de 25.0.1
Patrick Favre
2
Isso pode não funcionar se o usuário tiver vários idiomas instalados. Você deve usar, LocaleList.getDefault().get(0);pois isso retornará as localidades classificadas pelo idioma preferido.
Encaracolado
21
@FedericoPonzi @ for3st Encontrei isso em ConfigurationCompat, comoConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval
63

Se você estiver usando a Biblioteca de Suporte do Android, poderá usar ConfigurationCompato método do @ Makalele para se livrar dos avisos de descontinuação:

Locale current = ConfigurationCompat.getLocales(getResources().getConfiguration()).get(0);

ou em Kotlin:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]
ElegyD
fonte
8
Se você não tem qualquer contexto que você também pode fazerConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.
@QuentinG. Sim, mas é melhor usar o contexto do aplicativo neste caso.
McMath
Portanto, para deixar claro, isso não retornará a localidade padrão, mas o local preferido do usuário?
Csaba Toth
12

Da getDefaultdocumentação:

Retorna a localidade preferida do usuário. Isso pode ter sido substituído por esse processo com setDefault (Locale).

Também a partir dos Localedocumentos:

O código do idioma padrão é apropriado para tarefas que envolvem a apresentação de dados ao usuário.

Parece que você deveria usá-lo.

kabuko
fonte
7
esta resposta está errada, obtém um código de idioma padrão, mas se o usuário o alterou em tempo real, ele mostra errado. A próxima resposta está correta
user170317
concordou, resposta errada. No meu caso, estava procurando uma maneira de não precisar usar getResources (), o que significa que preciso de um contexto. Meu problema era uma classe auxiliar que não tinha um contexto, mas acho que vou ter que passar adiante. Se você tiver um aplicativo que permita que as pessoas alterem sua localidade e que tenham as sequências de visualizações, os formatos de número, etc. você precisa usar a resposta de Devunwired
1mike12
Trabalhe para mim. Se eu definir um ponto de interrupção Locale.setDefault(), ele começa é chamado quando eu mudar o idioma do dispositivo, pelo menos, de volta ao Android 5.0 (que é tão longe como eu testei)
cambunctious
6

Todas as respostas acima - não funcionam. Então eu vou colocar aqui uma função que funciona no android 4 e 9

private String getCurrentLanguage(){
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
      return LocaleList.getDefault().get(0).getLanguage();
   } else{
      return Locale.getDefault().getLanguage();
   }
}
Александр Остапюк
fonte
Uma das poucas respostas que retorna a direção de idioma preferida do usuário no nível do dispositivo. Você também pode usar LocaleListCompat.getDefault()se usar o AndroidX.
Sam
1

Eu usei isso:

String currentLanguage = Locale.getDefault().getDisplayLanguage();
if (currentLanguage.toLowerCase().contains("en")) {
   //do something
}
fvaldivia
fonte
0

De acordo com a documentação oficial , o ConfigurationCompat foi descontinuado nas bibliotecas de suporte

Você pode considerar usar

LocaleListCompat.getDefault()[0].toLanguageTag() A posição 0 será o local preferido do usuário

Para obter a localidade padrão na posição 0, seria LocaleListCompat.getAdjustedDefault()

Rakshit Soni
fonte
Sim, mas não foi substituído pela versão androidx ConfigurationCompat, consulte developer.android.com/reference/androidx/core/os/…
DragonLord
Correto, talvez seja mencionado apenas por causa da migração do androidx
Rakshit Soni 28/01