Android obtiene la configuración regional actual, no predeterminada

300

¿Cómo obtengo la configuración regional actual del usuario en Android?

Puedo obtener el predeterminado, pero puede que este no sea el correcto.

Básicamente quiero el código de idioma de dos letras de la configuración regional actual. No es el predeterminado. No hayLocale.current()

CQM
fuente
default()es una apuesta bastante segura, simplemente no la use para procesar (como dicen los documentos).
A - C
@ A - C ¿lo usa para procesar?
CQM
Sí, mira lo que dicen los documentos : algunas configuraciones regionales usarán ',' como punto decimal y '.' para agrupación de dígitos. entonces cosas como parseInt () pueden fallar. Tenga en cuenta que todavía recomiendan usar default(), pero no para cosas que pueden romper el código.
A - C

Respuestas:

487

El valor predeterminado Localese construye estáticamente en tiempo de ejecución para el proceso de su aplicación a partir de la configuración de propiedades del sistema, por lo que representará lo Localeseleccionado en ese dispositivo cuando se inició la aplicación . Por lo general, esto está bien, pero significa que si el usuario cambia su Localeconfiguración después de que se esté ejecutando el proceso de su aplicación, el valor de getDefaultLocale()probablemente no se actualizará de inmediato.

Si necesita atrapar eventos como este por alguna razón en su aplicación, puede intentar obtener los Localedisponibles del Configurationobjeto de recurso , es decir

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

Es posible que este valor se actualice más rápidamente después de un cambio de configuración si es necesario para su aplicación.

Devunwired
fuente
1
¿Alguien comprobó que la configuración regional predeterminada no cambia en la aplicación cuando la cambia en el sistema? Creo que es uno de esos "cambios de configuración" que hacen que las actividades sean destruidas y recreadas
Michał K
11
Lo probé, produciendo ambos mientras seguía cambiando la configuración regional; El resultado es que la salida es la misma. Por lo tanto, Locale.getDefault () se puede usar de forma segura a medida que se actualiza de inmediato. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio
58
Esto ha quedado en desuso en la clase de Configuración, consulte los últimos documentos para este consejo: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
77
¿por qué no solo agregan un método getFirstLocale () para evitar ese extraño getLocales (). get (0)?
user3290180
1
¿Qué sucede si desea admitir versiones anteriores y nuevas de api?
Ivan
179

Actualización de Android N (Api nivel 24) (sin advertencias):

   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
fuente
66
¿Hay algo en la biblioteca de soporte para evitar el if-else?
Federico Ponzi
8
@TargetApi (Build.VERSION_CODES.N) no es necesario en su código si incluye el código if y fallback
Patrick Favre
@FedericoPonzi no ResourceCompat no parece tener un método para la configuración regional a partir del 25.0.1
Patrick Favre
2
Esto puede no funcionar si el usuario tiene instalados varios idiomas. Debe usarlo LocaleList.getDefault().get(0);ya que esto devolverá las configuraciones regionales ordenadas por el idioma preferido.
Rizado
21
@FedericoPonzi @ for3st Encontré esto en ConfigurationCompat, comoConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval
63

Si está utilizando la Biblioteca de soporte de Android, puede usar en ConfigurationCompatlugar del método de @ Makalele para deshacerse de las advertencias de desaprobación:

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

o en Kotlin:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]
ElegyD
fuente
8
Si no tiene ningún contexto, también puede hacerloConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.
@QuentinG. Sí, pero es mejor usar el contexto de la aplicación en este caso.
McMath
Para que quede claro, ¿esto no devolverá la configuración regional predeterminada, pero la configuración regional preferida por el usuario?
Csaba Toth
12

De getDefaultla documentación de:

Devuelve la configuración regional preferida del usuario. Esto puede haberse anulado para este proceso con setDefault (Locale).

También de los Localedocumentos:

La configuración regional predeterminada es apropiada para tareas que implican presentar datos al usuario.

Parece que deberías usarlo.

kabuko
fuente
77
esta respuesta es incorrecta, tiene una configuración regional predeterminada pero si el usuario la cambió al vuelo, se muestra incorrecta. siguiente respuesta es correcta
usuario170317
De acuerdo, respuesta incorrecta. En mi caso, estaba buscando una manera de no tener que usar getResources (), lo que significa que necesito un contexto. Mi problema era una clase auxiliar que no tenía un contexto, pero supongo que tendré que transmitirla. Si tiene una aplicación que permite a las personas cambiar su ubicación y cambiar las cadenas de las vistas, los formatos de números, etc., entonces necesitas usar la respuesta de
Devunwired
Trabaja para mi. Si fijo en un punto de interrupción Locale.setDefault(), se consigue de llamadas cuando cambio el idioma del dispositivo, al menos, volver a Android 5.0 (que es por lo que he probado)
cambunctious
6

Todas las respuestas anteriores: no funcionan. Así que pondré aquí una función que funciona en Android 4 y 9

private String getCurrentLanguage(){
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
      return LocaleList.getDefault().get(0).getLanguage();
   } else{
      return Locale.getDefault().getLanguage();
   }
}
Александр Остапюк
fuente
Una de las pocas respuestas que devuelve la dirección de idioma preferida del usuario a nivel de dispositivo. También puedes usarlo LocaleListCompat.getDefault()si usas AndroidX.
Sam
1

He usado esto:

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

Según la documentación oficial ConfigurationCompat está en desuso en las bibliotecas de soporte

Puedes considerar usar

LocaleListCompat.getDefault()[0].toLanguageTag() La posición 0 será la configuración regional preferida por el usuario

Para obtener la configuración regional predeterminada en la posición 0 sería LocaleListCompat.getAdjustedDefault()

Rakshit Soni
fuente
Sí, pero no se ha reemplazado con la versión Androidx ConfigurationCompat, consulte developer.android.com/reference/androidx/core/os/…
DragonLord
Correcto, tal vez solo se menciona debido a la migración de Androidx
Rakshit Soni