Установите Locale программно

139

Мое приложение поддерживает 3 (скоро 4) языка. Поскольку несколько локалей очень похожи, я бы хотел, чтобы пользователь мог изменить локаль в моем приложении, например, итальянец может предпочесть испанский, а не английский.

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

Roland
источник
Если вам нужен способ восстановить локаль по умолчанию позже или если вам нужна языковая настройка, содержащая список языков, и если вы хотите изменить локаль более удобно, это может быть полезно: github.com/delight-im/Android -языков
каркать

Ответы:

114

Для тех, кто все еще ищет этот ответ, поскольку он configuration.localeбыл устаревшим из API 24, теперь вы можете использовать:

configuration.setLocale(locale);

Примите во внимание, что minSkdVersion для этого метода - API 17.

Полный пример кода:

@SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

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

РЕДАКТИРОВАТЬ 11 мая 2018

Начиная с поста @ CookieMonster, у вас могут возникнуть проблемы с сохранением изменения локали в более высоких версиях API. Если это так, добавьте следующий код в базовую активность, чтобы обновлять локаль контекста при каждом создании операции:

@Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration())
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

Если вы используете это, не забудьте сохранить язык в SharedPreferences, когда вы устанавливаете локаль с setLocate(locale)

РЕДАКТИРОВАТЬ 7-го АПРЕЛЯ 2020

Возможно, у вас проблемы с Android 6 и 7, и это происходит из-за проблем в библиотеках androidx при работе в ночном режиме. Для этого вам также потребуется переопределить applyOverrideConfigurationбазовое действие и обновить языковой стандарт конфигурации в случае создания нового нового языкового стандарта.

Образец кода:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale  
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
} 
Рикардо
источник
2
Это работает для действий, но есть ли способ обновить контекст приложения?
alekop
2
После изменения androidx.appcompat:appcompat:версии от 1.0.2до 1.1.0не работает на Android 7, но работать на андроид 9.
Бека
4
Та же проблема для меня и для 1.1.0androidx
Александр Дадукин
2
Та же проблема для меня. После того, как я перешел на androidx.appcompat: appcompat: 1.1.0 'lib
Рахул
4
Проблема с appcompat:1.1.0может быть исправлена ​​с помощью appcompat:1.2.0-alpha02кода и Set<Locale> set = new LinkedHashSet<>(); // bring the target locale to the front of the list set.add(locale); LocaleList all = LocaleList.getDefault(); for (int i = 0; i < all.size(); i++) { // append other locales supported by the user set.add(all.get(i)); } Locale[] locales = set.toArray(new Locale[0]); configuration.setLocales(new LocaleList(locales));внутри@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl
178

Надеюсь, что это поможет (в onResume):

Locale locale = new Locale("ru");
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());
Rubycon
источник
2
Так это должно быть установлено для каждого вида деятельности?
Тобиас
6
1. обязательно использовать getBaseContext () или лучше использовать контекст приложения? 2. этот код должен вызываться в каждом действии? Спасибо.
Пол
10
Я поместил этот код в onCreate () моего средства запуска (и нигде больше) и был приятно удивлен, увидев, что локаль применима ко всему приложению. Это приложение предназначено для 4.3 с minSDK 14 (ICS).
IAmKale
8
Нет необходимости создавать новый объект конфигурации. Вы можете использовать текущую конфигурацию и обновить ее: getResources (). GetConfiguration ()
jmart
1
не используйте новую конфигурацию (); она изменяет textAppearance, fontSize
Джемшит Искендеров
22

У меня была проблема с программной настройкой локали на устройствах с ОС Android N и выше . Для меня решением было написать этот код в моей основной деятельности:

(если у вас нет базовой активности, вы должны внести эти изменения во все ваши действия)

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPref.getInstance().getSavedLanguage();
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

обратите внимание, что здесь не достаточно позвонить

createConfigurationContext(configuration)

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

Печеньковый монстр
источник
Это самое простое и рабочее решение! Это должен быть принятый ответ.
Прасад Павар
3
Этот код отлично работает на Android выше 7, но в версиях ниже N не работает. Есть ли у вас какие-либо решения?
Матин Аштиани
Не уверен, потому что это работает для меня. Вы хотите отправить мне свою реализацию, чтобы я мог посмотреть?
CookieMonster
2
Не работает в версиях под Android N, потому что resources.updateConfiguration должен вызываться в onCreate () вместо attachBaseContext ()
Чандлер
@ Чандлер прав. Для Android 6 - вызовите updateBaseContextLocaleметод в onCreateвашей родительской / основной деятельности.
Азизжон Холматов
22

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

Главная Информация

Во-первых, существуют некоторые библиотеки, которые хотят решить проблему, но все они кажутся устаревшими или не имеют некоторых функций:

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

Мое решение в основном основано на https://github.com/gunhansancar/ChangeLanguageExample (как уже связано с localhost ). Это лучший код для поиска. Некоторые замечания:

  • При необходимости, он предоставляет различные реализации для изменения локали для Android N (и выше) и ниже
  • Он использует метод updateViews()в каждом действии, чтобы вручную обновить все строки после изменения локали (используя обычный getString(id)), что не является необходимым в подходе, показанном ниже
  • Поддерживаются только языки, а не полные локали (которые также включают регион (страну) и коды вариантов)

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

Решение

Решение состоит из следующих двух шагов:

  • Навсегда изменить локаль, которая будет использоваться приложением
  • Заставьте приложение использовать пользовательский набор языковых настроек без перезапуска

Шаг 1: Измените локаль

Используйте класс LocaleHelper, основанный на LocaleHelper от gunhansancar :

  • Добавить ListPreferenceв PreferenceFragmentс доступными языками (необходимо сохранить, когда языки должны быть добавлены позже)
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;

import java.util.Locale;

import mypackage.SettingsFragment;

/**
 * Manages setting of the app's locale.
 */
public class LocaleHelper {

    public static Context onAttach(Context context) {
        String locale = getPersistedLocale(context);
        return setLocale(context, locale);
    }

    public static String getPersistedLocale(Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SettingsFragment.KEY_PREF_LANGUAGE, "");
    }

    /**
     * Set the app's locale to the one specified by the given String.
     *
     * @param context
     * @param localeSpec a locale specification as used for Android resources (NOTE: does not
     *                   support country and variant codes so far); the special string "system" sets
     *                   the locale to the locale specified in system settings
     * @return
     */
    public static Context setLocale(Context context, String localeSpec) {
        Locale locale;
        if (localeSpec.equals("system")) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                locale = Resources.getSystem().getConfiguration().getLocales().get(0);
            } else {
                //noinspection deprecation
                locale = Resources.getSystem().getConfiguration().locale;
            }
        } else {
            locale = new Locale(localeSpec);
        }
        Locale.setDefault(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, locale);
        } else {
            return updateResourcesLegacy(context, locale);
        }
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, Locale locale) {
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, Locale locale) {
        Resources resources = context.getResources();

        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLayoutDirection(locale);
        }

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }
}

Создайте SettingsFragmentподобное:

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * Fragment containing the app's main settings.
 */
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_LANGUAGE = "pref_key_language";

    public SettingsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        return view;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        switch (key) {
            case KEY_PREF_LANGUAGE:
                LocaleHelper.setLocale(getContext(), PreferenceManager.getDefaultSharedPreferences(getContext()).getString(key, ""));
                getActivity().recreate(); // necessary here because this Activity is currently running and thus a recreate() in onResume() would be too late
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // documentation requires that a reference to the listener is kept as long as it may be called, which is the case as it can only be called from this Fragment
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
}

Создайте ресурс со locales.xmlсписком всех локалей с доступными переводами следующим образом ( список кодов локали ):

<!-- Lists available locales used for setting the locale manually.
     For now only language codes (locale codes without country and variant) are supported.
     Has to be in sync with "settings_language_values" in strings.xml (the entries must correspond).
  -->
<resources>
    <string name="system_locale" translatable="false">system</string>
    <string name="default_locale" translatable="false"></string>
    <string-array name="locales">
        <item>@string/system_locale</item> <!-- system setting -->
        <item>@string/default_locale</item> <!-- default locale -->
        <item>de</item>
    </string-array>
</resources>

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

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/preferences_category_general">
        <ListPreference
            android:key="pref_key_language"
            android:title="@string/preferences_language"
            android:dialogTitle="@string/preferences_language"
            android:entries="@array/settings_language_values"
            android:entryValues="@array/locales"
            android:defaultValue="@string/system_locale"
            android:summary="%s">
        </ListPreference>
    </PreferenceCategory>
</PreferenceScreen>

который использует следующие строки из strings.xml:

<string name="preferences_category_general">General</string>
<string name="preferences_language">Language</string>
<!-- NOTE: Has to correspond to array "locales" in locales.xml (elements in same orderwith) -->
<string-array name="settings_language_values">
    <item>Default (System setting)</item>
    <item>English</item>
    <item>German</item>
</string-array>

Шаг 2. Заставьте приложение использовать пользовательский язык

Теперь настройте каждое действие, чтобы использовать пользовательский набор языковых стандартов. Самый простой способ сделать это - иметь общий базовый класс для всех действий со следующим кодом (где находится важный код attachBaseContext(Context base)и onResume()):

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * {@link AppCompatActivity} with main menu in the action bar. Automatically recreates
 * the activity when the locale has changed.
 */
public class MenuAppCompatActivity extends AppCompatActivity {
    private String initialLocale;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initialLocale = LocaleHelper.getPersistedLocale(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                Intent intent = new Intent(this, SettingsActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (initialLocale != null && !initialLocale.equals(LocaleHelper.getPersistedLocale(this))) {
            recreate();
        }
    }
}

Что это делает

  • Переопределить, attachBaseContext(Context base)чтобы использовать локаль, ранее сохраненную сLocaleHelper
  • Определите изменение языкового стандарта и заново создайте Activity, чтобы обновить его строки

Примечания к этому решению

  • Воссоздание Действия не обновляет заголовок ActionBar (как уже наблюдалось здесь: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).

    • Это может быть достигнуто простым введением setTitle(R.string.mytitle)в onCreate()методе каждого действия.
  • Это позволяет пользователю выбрать системный языковой стандарт по умолчанию, а также языковой стандарт приложения по умолчанию (который может быть назван, в данном случае «английский»).

  • fr-rCAПока поддерживаются только языковые коды, ни регион (страна), ни коды вариантов (например ). Для поддержки полных спецификаций локали можно использовать синтаксический анализатор, подобный таковому в библиотеке Android-Languages (который поддерживает регион, но без кодов вариантов).

    • Если кто-то найдет или написал хороший анализатор, добавьте комментарий, чтобы я мог включить его в решение.
user905686
источник
1
Отлично, но король кошмара
Odys
1
Черт возьми, мое приложение уже слишком сложное, такой подход будет кошмаром в будущем.
Джош
@ Джош Можете ли вы объяснить это немного дальше? На самом деле к каждому используемому базовому классу Activity нужно добавить всего несколько строк. Я вижу, что может быть невозможно использовать один и тот же базовый класс для всех видов деятельности, но даже более крупные проекты должны быть в состоянии ужиться с несколькими. Здесь может помочь аспектно-ориентированное программирование, но составление (перемещение кода из attachBaseContext(Context base)и onResume()в отдельный класс) может помочь. Затем все, что вам нужно сделать, это объявить один объект в каждом базовом классе активности и делегировать эти два вызова.
user905686
Если пользователь меняет свой языковой стандарт, можно ли изменить языковой стандарт всех предыдущих страниц действий?
Raju yourPepe
Это лучший ответ по этому вопросу. Спасибо, братан, это работает
Алок Гупта
16
@SuppressWarnings("deprecation")
public static void forceLocale(Context context, String localeCode) {
    String localeCodeLowerCase = localeCode.toLowerCase();

    Resources resources = context.getApplicationContext().getResources();
    Configuration overrideConfiguration = resources.getConfiguration();
    Locale overrideLocale = new Locale(localeCodeLowerCase);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        overrideConfiguration.setLocale(overrideLocale);
    } else {
        overrideConfiguration.locale = overrideLocale;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.getApplicationContext().createConfigurationContext(overrideConfiguration);
    } else {
        resources.updateConfiguration(overrideConfiguration, null);
    }
}

Просто используйте этот вспомогательный метод для принудительного определения конкретной локали.

UDPATE 22 августа 2017 года. Лучше использовать этот подход .

локальный
источник
4

Добавьте вспомогательный класс с помощью следующего метода:

public class LanguageHelper {
    public static final void setAppLocale(String language, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Resources resources = activity.getResources();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(new Locale(language));
            activity.getApplicationContext().createConfigurationContext(configuration);
        } else {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Configuration config = activity.getResources().getConfiguration();
            config.locale = locale;
            activity.getResources().updateConfiguration(config,
                    activity.getResources().getDisplayMetrics());
        }

    }
}

И назовите это в своей деятельности запуска, как MainActivity.java:

public void onCreate(Bundle savedInstanceState) {
    ...
    LanguageHelper.setAppLocale("fa", this);
    ...
}
Хадид графика
источник
3

просто и легко

Locale locale = new Locale("en", "US");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = locale;
res.updateConfiguration(conf, dm);

где «en» - это код языка, а «US» - код страны.

Makvin
источник
Как указано в моем посте conf.locale=locale;не рекомендуется, а также является updateConfiguration.
Рикардо
очень просто и менее сложно :)
Рамкеш Ядав
2

Действительно от API16 до API28. Просто поместите этот метод где-нибудь:

    Context newContext = context;

        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

        config.setLocale(locale);
                newContext = context.createConfigurationContext(config);

        } else {

        config.locale = locale;
                resources.updateConfiguration(config, resources.getDisplayMetrics());
        }

    return newContext;
}

Вставьте этот код во все ваши действия, используя:

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(localeUpdateResources(base, "<-- language code -->"));
    }

или вызовите localeUpdateResources для фрагментов, адаптеров и т. д., где вам нужен новый контекст.

Кредиты: Ярослав Березанский

nnyerges
источник
2

Есть супер простой способ.

в BaseActivity, Activity или Fragment переопределить attachBaseContext

 override fun attachBaseContext(context: Context) {
    super.attachBaseContext(context.changeLocale("tr"))
}

расширение

fun Context.changeLocale(language:String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)
    val config = this.resources.configuration
    config.setLocale(locale)
    return createConfigurationContext(config)
}
Бурак Дизлек
источник
2

Я обнаружил, что androidx.appcompat:appcompat:1.1.0ошибку можно исправить, просто позвонив getResources()вapplyOverrideConfiguration()

@Override public void
applyOverrideConfiguration(Configuration cfgOverride)
{
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
      Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    // add this to fix androidx.appcompat:appcompat 1.1.0 bug
    // which happens on Android 6.x ~ 7.x
    getResources();
  }

  super.applyOverrideConfiguration(cfgOverride);
}
Сэм Лу
источник
1
 /**
 * Requests the system to update the list of system locales.
 * Note that the system looks halted for a while during the Locale migration,
 * so the caller need to take care of it.
 */
public static void updateLocales(LocaleList locales) {
    try {
        final IActivityManager am = ActivityManager.getService();
        final Configuration config = am.getConfiguration();

        config.setLocales(locales);
        config.userSetLocale = true;

        am.updatePersistentConfiguration(config);
    } catch (RemoteException e) {
        // Intentionally left blank
    }
}
Збигнев Мазур
источник
1

Для тех, кто все пробовал, но не работает . Пожалуйста, проверьте, что если вы установили darkmodeс помощью, AppCompatDelegate.setDefaultNightModeи система не темно, то Configuration.setLocaleне будет работать выше Andorid 7.0 .

Добавьте этот код в каждое действие, чтобы решить эту проблему:

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
  if (overrideConfiguration != null) {
    val uiMode = overrideConfiguration.uiMode
    overrideConfiguration.setTo(baseContext.resources.configuration)
    overrideConfiguration.uiMode = uiMode
  }
  super.applyOverrideConfiguration(overrideConfiguration)
}
Yeahia2508
источник
-1

Поместите этот код в вашу деятельность

 if (id==R.id.uz)
    {
        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
        return true;
    }
    if (id == R.id.ru) {

        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
    }
Ксуршид Раксматов
источник