Android отримує поточний Locale, не за замовчуванням


300

Як отримати поточний Locale користувача в Android?

Я можу отримати за замовчуванням, але це може бути не правильним?

В основному я хочу, щоб двомовний код мови з поточної мови. Не за замовчуванням. НемаєLocale.current()


default()це досить безпечна ставка, просто не використовуйте її для обробки (як кажуть документи).
A - C

@ A - C використовувати його для обробки?
CQM

Так, подивіться, що кажуть документи : деякі локалі використовуватимуть ',' у вигляді десяткової крапки і '.' для згрупування цифр. тому такі речі, як parseInt (), можуть не працювати. Зауважте, що вони все ж рекомендують використовувати default(), але не для речей, які можуть порушити код.
A - C

Відповіді:


487

За замовчуванням Localeпобудовано статично під час виконання вашого додатка з налаштувань системних властивостей, тому він буде представляти Localeвибраний на цьому пристрої під час запуску програми . Як правило, це нормально, але це означає, що якщо користувач змінить свої Localeналаштування після запуску вашого додатка, значення, getDefaultLocale()ймовірно, не буде одразу оновлено.

Якщо вам потрібно чомусь захопити подібні події у вашій програмі, ви можете замість цього спробувати отримати Localeдоступне від ресурсу Configurationоб’єкт, тобто

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

Ви можете виявити, що це значення оновлюється швидше після зміни налаштувань, якщо це необхідно для вашої програми.


1
Хтось перевіряв, чи не змінюється локальний код за замовчуванням у додатку, коли ви змінюєте його в системі? Я думаю, що це одна з тих "змін конфігурації", які роблять діяльність знищеною та відтвореною
Michał K

11
Я тестував це, виводячи обидва, поки я продовжував змінювати мову; Результат - вихід однаковий. Тож Locale.getDefault () можна безпечно використовувати, оскільки він одразу оновлюється. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Алессіо

58
Це клас застаріло в класі Конфігурація, дивіться останні документи щодо цієї поради: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
чому вони просто не додають метод getFirstLocale (), щоб уникнути цього дивного getLocales (). get (0)?
користувач3290180

1
Що робити, якщо ви хочете підтримувати старіші та новіші версії api?
Іван

179

Оновлення Android N (рівень Api 24) (без попереджень):

   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
Чи є в бібліотеці підтримки щось, щоб уникнути цього?
Федеріко Понці

8
@TargetApi (Build.VERSION_CODES.N) не потрібен у вашому коді, якщо ви включаєте код if і backback
Patrick Favre

@FedericoPonzi no ResourceCompat, здається, не має методу локалізації станом на 25.0.1
Патрік Фавре

2
Це може не працювати, якщо у користувача встановлено кілька мов. Ви повинні використовувати, LocaleList.getDefault().get(0);оскільки це поверне Локали, відсортовані за бажаною мовою.
Кучеряве

21
@FedericoPonzi @ for3st Я знайшов це в ConfigurationCompat, якConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
липня 1717

63

Якщо ви користуєтеся бібліотекою підтримки Android, ConfigurationCompatзамість методу @ Makalele ви можете позбутися попереджень про депресацію:

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

або в Котліні:

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

8
Якщо у вас немає жодного контексту, ви також можете зробити цеConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Квентін Г.

@QuentinG. Так, але краще використовувати контекст програми в цьому випадку.
Макмат

Щоб було зрозуміло, це не поверне локаль за замовчуванням, але користувач віддав перевагу мові?
Csaba Toth

12

З getDefaultросійської документації:

Повертає бажаний локальний користувач. Це можливо було замінено для цього процесу за допомогою setDefault (Locale).

Також із Localeдокументів:

Мова за замовчуванням підходить для завдань, що передбачають представлення даних користувачеві.

Здається, ви повинні просто використовувати його.


7
ця відповідь неправильна, має місце за замовчуванням, але якщо користувач змінив його на льоту, він виявиться неправильним. наступна відповідь правильна
user170317

погоджена, неправильна відповідь. У моєму випадку я шукав спосіб не потрібно використовувати getResources (), а значить, мені потрібен контекст. Моєю проблемою був клас помічників, у якого не було контексту, але, мабуть, мені доведеться передати його. Якщо у вас є додаток, який дозволяє людям змінювати свою локаль і змінювати рядки перегляду, формати чисел тощо, то, то вам потрібно скористатися відповіддю
Devunwired

Працюй для мене. Якщо я встановив точку перерви в Locale.setDefault(), вона буде викликана, коли я зміню мову пристрою хоча б назад на Android 5.0 (це настільки, наскільки я тестував)
cambunstiti

6

Усі відповіді вище - не працюють. Тому я поставлю сюди функцію, яка працює на 4 та 9 андроїд

private String getCurrentLanguage(){
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
      return LocaleList.getDefault().get(0).getLanguage();
   } else{
      return Locale.getDefault().getLanguage();
   }
}

Один з небагатьох відповідей, який повертає бажаний мовний напрямок користувача на рівні пристрою. Ви також можете використовувати, LocaleListCompat.getDefault()якщо ви використовуєте AndroidX.
Сем

1

Я використовував це:

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

0

Згідно з офіційною документацією, ConfigurationCompat застарілий у бібліотеках підтримки

Ви можете розглянути можливість використання

LocaleListCompat.getDefault()[0].toLanguageTag() 0-а позиція буде кращим для користувача мовою

Отримати локаль за замовчуванням на 0-й позиції було б LocaleListCompat.getAdjustedDefault()


Так, але чи не було замінено версією androidx ConfigurationCompat, див. Developer.android.com/reference/androidx/core/os/…
DragonLord

Правильно, можливо, це згадується лише через міграцію
андроїд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.