Android получит локализацию устройства

После установки моей программы Android я проверяю локализацию устройства:

String deviceLocale=Locale.getDefault().getLanguage();

Если deviceLocale находится внутри моих поддерживаемых языков (английский, французский, немецкий), я не меняю языковой стандарт.

Но скажем, например, если я не поддерживаю язык устройства: например, испанский. Я устанавливаю текущую локаль на английский язык, потому что большинство людей могут понять английский частично.

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

Но после этого в других методах, когда я проверяю локализацию устройства следующим образом:

String deviceLocale=Locale.getDefault().getLanguage();

Я получаю результат как "английский". Но язык устройства - испанский.

Получает ли getLanguage() текущую локализацию приложения?
Как я могу получить локали устройства?

Изменить: в первом запуске приложения это вариант сохранения языкового стандарта устройства. Но если пользователь меняет локаль устройства после сохранения, я не могу знать новый язык устройства. Я могу узнать только локаль, которую я сохранил в приложении.

Ответ 1

Там намного проще и чище сделать это, чем использовать отражение или разбор некоторых системных свойств.

Как вы заметили, как только вы установили Locale по умолчанию в своем приложении, у вас больше нет доступа к системному языку по умолчанию. Стандартная локаль, установленная в вашем приложении, действительна только в течение жизненного цикла вашего приложения. Все, что вы установили в своем Locale.setDefault(Locale), исчезнет после завершения процесса. Когда приложение будет перезапущено, вы снова сможете прочитать системный каталог по умолчанию.

Итак, все, что вам нужно сделать, - это восстановить системный язык по умолчанию при запуске приложения, запомните его, пока приложение запускается и обновляется, если пользователь решит изменить язык в настройках Android. Поскольку нам нужна эта информация только до тех пор, пока приложение запускается, мы можем просто сохранить ее в статической переменной, доступной из любого места в вашем приложении.

И вот как мы это делаем:

public class MyApplication extends Application {

    public static String sDefSystemLanguage;

    @Override
    public void onCreate() {
        super.onCreate();

        sDefSystemLanguage = Locale.getDefault().getLanguage();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        sDefSystemLanguage = newConfig.locale.getLanguage();
    }

}

Используя приложение (не забудьте определить его в манифесте), мы получаем локаль по умолчанию при запуске приложения (onCreate()), и мы обновляем его, когда пользователь меняет язык в настройках Android (onConfigurationChanged (Конфигурация) )). Это все есть. Всякий раз, когда вам нужно знать, что такое системный язык по умолчанию, прежде чем использовать вызов setDefault, sDefSystemLanguage даст вам ответ.

Там один вопрос, который я заметил в вашем коде. Когда вы устанавливаете новую локаль, вы делаете:

Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

При этом вы перезаписываете всю информацию о конфигурации, которую вы хотите сохранить. Например. Configuration.fontScale отражает настройки специальных возможностей Large Text. По настройкам язык и потеря всех других настроек вашего приложения больше не будут отображаться в настройках большого текста, то есть текст меньше, чем должен быть (если пользователь включил большую настройку текста). Правильный способ сделать это:

Resources res = pContext.getResources();
Configuration config = res.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    configuration.setLocale(Locale.CANADA);
}
else {
    configuration.locale = Locale.CANADA;
}
res.updateConfiguration(config, null);

Итак, вместо создания нового объекта Configuration мы просто обновляем текущий.

Ответ 2

Доступ к глобальному языку можно получить с помощью

defaultLocale = Resources.getSystem().getConfiguration().locale;

Взгляните на http://developer.android.com/reference/android/content/res/Resources.html#getSystem() -

Возвращает глобальный общий ресурс, который предоставляет доступ только к системным ресурсам (без ресурсов приложения)

Обновление: как указано в поле комментариев "locale", устарело, и вам нужно вместо этого использовать getLocales().

defaultLocale = Resources.getSystem().getConfiguration().getLocales().get(0);

Ответ 3

Лучший способ разработки приложения - использовать по умолчанию lang, английский в вашем случае, под значениями /, и вы можете добавить дополнительные langs под значениями-XX/. Таким образом, когда язык не поддерживается, Android отказывается от вашего по умолчанию, поэтому на английском языке. Пусть ОС сделает для вас работу:) Однако да, если вы измените локаль, вы получите свои последние настройки, поэтому вы должны где-то сохранить эту информацию.

Ответ 4

По мере изменения Application language programatically like

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

И

But after that, in other methods, when I check device locale like this:

String deviceLocale=Locale.getDefault().getLanguage();
I get result as "English". But device locale is Spanish.

Поэтому вместо этого используйте этот ниже код, чтобы получить device Local

try {
    Process exec = Runtime.getRuntime().exec(new String[]{"getprop", "persist.sys.language"});
    String locale = new BufferedReader(new InputStreamReader(exec.getInputStream())).readLine();
    exec.destroy();
    Log.e("", "Device locale: "+locale);
} catch (IOException e) {
    e.printStackTrace();
}

ВЫХОД: Spanish Проверьте это

Надеюсь, это именно то, что вы ищете.

Ответ 5

вы должны использовать String deviceLocale= Locale.getDefault().getDisplayLanguage(); для отображения языка вместо

String deviceLocale=Locale.getDefault().getLanguage();

проверить этот ответ, он может помочь вам, если выше этого нет. Нажмите

Ответ 6

Хотя ответ @user2944616 является политически корректным, что не дает ответа на фактический поставленный вопрос.

Итак, если мне действительно нужно знать языковой стандарт системы пользователя, я бы использовал отражение (не знаю лучшего ATM):

private String getSystemPropertyValue(String name) {
    try {
        Class<?> systemProperties = Class.forName("android.os.SystemProperties");
        try {
            Method get = systemProperties.getMethod("get", String.class, String.class);
            if (get == null) {
                return "Failure!?";
            }
            try {
                return (String)get.invoke(systemProperties, name, "");
            } catch (IllegalAccessException e) {
                return "IllegalAccessException";
            } catch (IllegalArgumentException e) {
                return "IllegalArgumentException";
            } catch (InvocationTargetException e) {
                return "InvocationTargetException";
            }
        } catch (NoSuchMethodException e) {
            return "SystemProperties.get(String key, String def) method is not found";
        }
    } catch (ClassNotFoundException e) {
        return "SystemProperties class is not found";
    }
}

С учетом этого и языкового стандарта устройства, установленного на испанский (США)/Español (Estados Unidos) следующую строку

<string name="system_locale">System locale: <xliff:g id="profile_name">%1$s</xliff:g>&#95;<xliff:g id="device_name">%2$s</xliff:g></string>

и этот код

private static final String SYS_COUNTRY = "persist.sys.country";
private static final String SYS_LANG = "persist.sys.language";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = (TextView)findViewById(R.id.locale);
    tv.setText(getString(R.string.system_locale, getSystemPropertyValue(SYS_LANG),
            getSystemPropertyValue(SYS_COUNTRY)));
}

выводит следующий экран:

System locale screenshot

При желании можно также легко построить экземпляр Locale, используя приведенное выше:

Locale locale = new Locale(getSystemPropertyValue(SYS_LANG),
        getSystemPropertyValue(SYS_COUNTRY));
Log.d(TAG, "Language: " + locale.getLanguage());
Log.d(TAG, "Country: " + locale.getCountry());

Выход журнала:

D/GetSystemLocale(5697): Language: es
D/GetSystemLocale(5697): Country: US

Надеюсь, что это поможет.

Ответ 7

для тех, кто использует Amit Gupta Ответ на последнее решение, которое:

Process exec = Runtime.getRuntime().exec(new String[]{"getprop", "persist.sys.language"});
String locale = new BufferedReader(new InputStreamReader(exec.getInputStream())).readLine();
exec.destroy();

Имейте в виду, что этот локаль может быть EMPTY на последней версии Android Api! вместо использования persist.sys.language используйте persist.sys.locale

exec = Runtime.getRuntime().exec(new String[]{"getprop", "persist.sys.locale"});
locale = new BufferedReader(new InputStreamReader(exec.getInputStream())).readLine();
exec.destroy();

Ответ 8

Чтобы получить локаль устройства, используйте

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

и current.toString() вернут вам "en" "ar" и т.д.