Android ottiene le impostazioni internazionali correnti, non predefinite


300

Come posso ottenere le impostazioni internazionali correnti dell'utente su Android?

Posso ottenere quello predefinito, ma questo potrebbe non essere quello attuale corretto?

Fondamentalmente voglio il codice della lingua di due lettere dalla locale corrente. Non quello predefinito. Non c'èLocale.current()


default()è una scommessa abbastanza sicura, ma non usarla per l'elaborazione (come dicono i documenti).
A - C

@ A - C lo usi per l'elaborazione?
CQM,

Sì, guarda cosa dicono i documenti : alcuni locali useranno "," come punto decimale e "." per il raggruppamento delle cifre. quindi cose come parseInt () potrebbero fallire. Nota che raccomandano ancora di usare default(), ma non per cose che possono violare il codice.
A - C

Risposte:


487

Il valore predefinito Localeè costruito staticamente in fase di esecuzione per il processo dell'applicazione dalle impostazioni delle proprietà del sistema, quindi rappresenterà il Localeselezionato su quel dispositivo all'avvio dell'applicazione . In genere, va bene, ma significa che se l'utente modifica le proprie Localeimpostazioni dopo l'esecuzione del processo dell'applicazione, il valore di getDefaultLocale()probabilmente non verrà immediatamente aggiornato.

Se è necessario intercettare eventi come questo per qualche motivo nella propria applicazione, è possibile invece provare a ottenere il Localedisponibile dall'oggetto risorsa Configuration, ad es.

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

È possibile che questo valore venga aggiornato più rapidamente dopo una modifica delle impostazioni, se necessario per la propria applicazione.


1
Qualcuno ha verificato che l'impostazione internazionale predefinita non è stata modificata nell'app quando è stata modificata nel sistema? Penso che sia uno di quei "cambiamenti di configurazione" che rendono le attività distrutte e ricreate
Michał K

11
L'ho provato, emettendo entrambi mentre continuavo a cambiare locale; il risultato è che l'output è lo stesso. Quindi Locale.getDefault () può essere utilizzato in modo sicuro poiché viene immediatamente aggiornato. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Alessio

58
Questo è stato deprecato nella classe Configuration, vedere gli ultimi documenti per questo consiglio: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
perché non aggiungono semplicemente un metodo getFirstLocale () per evitare quello strano getLocales (). get (0)?
user3290180

1
Cosa succede se si desidera supportare le versioni più vecchie e più recenti di api?
Ivan

179

Aggiornamento di Android N (Api livello 24) (nessun avviso):

   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;
        }
    }

6
C'è qualcosa nella libreria di supporto per evitare l'if-else?
Federico Ponzi,

8
@TargetApi (Build.VERSION_CODES.N) non è necessario nel tuo codice se includi il codice if e fallback
Patrick Favre l'

@FedericoPonzi no ResourceCompat non sembra avere un metodo per la localizzazione a partire dal 25.0.1
Patrick Favre l'

2
Questo potrebbe non funzionare se l'utente ha più lingue installate. È necessario utilizzare in LocaleList.getDefault().get(0);quanto restituirà le impostazioni locali ordinate in base alla lingua preferita.
Ricci,

21
@FedericoPonzi @ for3st L'ho trovato in ConfigurationCompat, asConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval

63

Se si utilizza la libreria di supporto Android, è possibile utilizzare ConfigurationCompatinvece del metodo @ Makalele per eliminare gli avvisi di deprecazione:

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

o in Kotlin:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]

8
Se non hai alcun contesto, puoi anche farloConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Quentin G.,

@QuentinG. Sì, ma è meglio utilizzare il contesto dell'applicazione in questo caso.
McMath,

Quindi, per essere chiari, questo non restituirà la locale predefinita ma l'utente preferisce la locale?
Csaba Toth,

12

Dalla getDefaultdocumentazione di:

Restituisce le impostazioni internazionali preferite dell'utente. Questo potrebbe essere stato ignorato per questo processo con setDefault (Locale).

Anche dai Localedocumenti:

Le impostazioni internazionali predefinite sono appropriate per le attività che comportano la presentazione di dati all'utente.

Sembra che dovresti semplicemente usarlo.


7
questa risposta è sbagliata, ha un'impostazione internazionale predefinita ma se l'utente l'ha cambiata al volo mostra che è sbagliata. la prossima risposta è corretta
user170317

concordato, risposta sbagliata. Nel mio caso, stavo cercando un modo per non dover usare getResources (), il che significa che ho bisogno di un contesto. Il mio problema era una classe di supporto che non aveva un contesto, ma suppongo che dovrò trasmetterlo. Se hai un'app che consente alle persone di cambiare il loro locale e far cambiare le stringhe delle viste, i formati numerici ecc., Allora devi usare la risposta di
Devunwired

Lavora per me. Se imposto un punto di interruzione suLocale.setDefault() , si ottiene chiama quando cambio la lingua del dispositivo, almeno torna ad Android 5.0 (che è quanto ho provato)
cambunctious

6

Tutte le risposte sopra - non funzionano. Quindi inserirò qui una funzione che funziona su 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();
   }
}

Una delle poche risposte che restituisce la direzione della lingua preferita dell'utente a livello di dispositivo. Puoi anche usarlo LocaleListCompat.getDefault()se usi AndroidX.
Sam,

1

Ho usato questo:

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

0

Come da documentazione ufficiale ConfigurationCompat è obsoleto nelle librerie di supporto

Puoi prendere in considerazione l'utilizzo

LocaleListCompat.getDefault()[0].toLanguageTag() La 0a posizione sarà la locale preferita dall'utente

Per ottenere le impostazioni internazionali predefinite in posizione 0 sarebbe LocaleListCompat.getAdjustedDefault()


Sì, ma non è stato sostituito con la versione di Androidx ConfigurationCompat, vedi developer.android.com/reference/androidx/core/os/…
DragonLord

Corretto, forse è menzionato solo a causa della migrazione di androidx
Rakshit Soni il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.