Android получает текущую локаль, а не по умолчанию

300

Как получить текущую локаль пользователя в 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;

Вы можете обнаружить, что это значение обновляется быстрее после изменения настроек, если это необходимо для вашего приложения.

Devunwired
источник
1
Кто-нибудь проверял, что языковой стандарт по умолчанию не изменяется в приложении при его изменении в системе? Я думаю, что это одно из тех «изменений конфигурации», которые делают действия уничтоженными и воссозданными
Михал К
11
Я проверял это, выводя оба, пока продолжал менять локаль; В результате получается то же самое. Таким образом, Locale.getDefault () можно безопасно использовать, поскольку он немедленно обновляется. Log.d("localeChange", "Default locale lang: " + Locale.getDefault().getLanguage()); Log.d("localeChange", "Config locale lang: " + getResources().getConfiguration().locale.getLanguage());
Алессио
58
Это было объявлено устаревшим в классе Configuration, см. Последние документы для этого совета: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)?
user3290180
1
Что делать, если вы хотите поддерживать более старые и новые версии API?
Иван
179

Обновление Android N (Api level 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;
        }
    }
Makalele
источник
6
Есть ли что-то в библиотеке поддержки, чтобы избежать if-else?
Федерико Понци
8
@TargetApi (Build.VERSION_CODES.N) не требуется в вашем коде, если вы включаете код if и запасной вариант
Патрик Фавр
@FedericoPonzi no ResourceCompat, по-видимому, не имеет метода для локали по состоянию на 25.0.1
Патрик Фавр
2
Это может не работать, если у пользователя установлено несколько языков. Вы должны использовать, так LocaleList.getDefault().get(0);как это вернет локали, отсортированные по предпочитаемому языку.
Кудрявый
21
@FedericoPonzi @ for3st Я нашел это в ConfigurationCompat, какConfigurationCompat.getLocales(getResources().getConfiguration()).get(0)
yuval
63

Если вы используете библиотеку поддержки Android, вы можете использовать ConfigurationCompatвместо метода @ Makalele избавление от предупреждений об устаревании:

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

или в Котлине:

val currentLocale = ConfigurationCompat.getLocales(resources.configuration)[0]
ElegyD
источник
8
Если у вас нет контекста, вы также можете это сделатьConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
Квентин Дж.
@QuentinG. Да, но лучше использовать контекст приложения в этом случае.
МакМэт
Таким образом, чтобы было ясно, это не вернет локаль по умолчанию, но пользователь предпочел локаль?
Чаба Тот
12

Из getDefaultдокументации:

Возвращает предпочтительный язык пользователя. Это могло быть переопределено для этого процесса с помощью setDefault (Locale).

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

Локаль по умолчанию подходит для задач, связанных с представлением данных пользователю.

Похоже, вы должны просто использовать его.

kabuko
источник
7
этот ответ неправильный, получил локаль по умолчанию, но если пользователь изменил его на лету, он показывает неверно. следующий ответ правильный
user170317
согласен, неправильный ответ. В моем случае я искал способ не использовать getResources (), что означает, что мне нужен контекст. Моя проблема заключалась в том, что у вспомогательного класса не было контекста, но, думаю, мне придется передать его. Если у вас есть приложение, которое позволяет людям менять их локаль и изменять строки представлений, числовые форматы и т. Д., То вам нужно использовать ответ
Devunwired
Работа для меня Если я устанавливаю точку останова на Locale.setDefault(), она вызывается, когда я меняю язык устройства, по крайней мере, обратно на Android 5.0 (насколько я тестировал)
cambuncsive
6

Все ответы выше - не работают. Поэтому я поставлю здесь функцию, которая работает на 4 и 9 Android

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
}
fvaldivia
источник
0

Согласно официальной документации, ConfigurationCompat устарела в библиотеках поддержки

Вы можете рассмотреть возможность использования

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

Чтобы получить локаль по умолчанию в 0-й позиции было бы LocaleListCompat.getAdjustedDefault()

Ракшит Сони
источник
Да , но не он был заменен на androidx версии ConfigurationCompat см developer.android.com/reference/androidx/core/os/...
Dragonlord
Правильно, может быть, это упоминается только из-за миграции
androidx