Встановіть програму Locale програмно


139

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

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


Якщо вам потрібен спосіб відновити мову за замовчуванням пізніше або вам потрібна мовна налаштування, що містить список мов, і якщо ви хочете зручніше змінити мову, це може бути корисним: github.com/delight-im/Android -Язи
caw

Відповіді:


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

Не забувайте, що якщо ви зміните локаль за допомогою запущеної діяльності, вам потрібно буде перезапустити його, щоб зміни вступили в силу.

РЕДАКЦІЯ 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
Це працює для діяльності, але чи є спосіб оновити контекст програми?
алекоп

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
Рахул Jidge

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());

2
Отже, це має бути встановлено для кожної діяльності?
Тобіас

6
1. обов'язково використовувати getBaseContext () або краще використовувати контекст програми? 2. цей код слід називати в кожній діяльності? Дякую.
Пол

10
Я помістив цей код у onCreate () моєї активності запуску (і ніде більше) і був приємно здивований, побачивши, що локал застосовано до всього додатка. Це в додатку, націленому на 4.3 з minSDK 14 (ICS).
IAmKale

8
Не потрібно створювати новий об’єкт конфігурації. Ви можете використовувати поточну конфігурацію та оновлювати її: getResources (). GetConfiguration ()
jmart

1
не використовуйте нову програму Configuration () ;, вона змінює textAppearance, fontSize
Jemshit Iskenderov

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методі.


Це найпростіше і працююче рішення! Це має бути прийнятою відповіддю.
Prasad Pawar

3
Цей код чудово працює на android вище 7, але у версіях нижче N не працює. Чи є у вас рішення?
Матін Аштіані

Не впевнений, бо це працює на мене. Ви хочете надіслати мені свою реалізацію, щоб я міг поглянути?
CookieMonster

2
Не працює у версіях під Android N, оскільки ресурси.updateConfiguration потрібно викликати в onCreate () замість attachBaseContext ()
Чандлер

@Chandler має рацію. Для 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
  • Визначте зміну локалі та відтворіть Активність, щоб оновити його рядки

Примітки до цього рішення

  • Відтворення діяльності не оновлює назву ActionBar (як це вже зазначалось тут: https://github.com/gunhansancar/ChangeLanguageExample/isissue/1 ).

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

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

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

1
Чудовий, але король кошмару
Одіс

1
Чорт, ні, моя програма вже занадто складна, такий підхід був би кошмаром, який слід підтримувати в майбутньому.
Джош

@Josh Чи можете ви пояснити це трохи далі? Насправді лише кілька рядків потрібно додати до кожного базового класу діяльності, який ви використовуєте. Я бачу, що можливо використовувати один і той же базовий клас для всіх видів діяльності, але навіть більші проекти повинні мати можливість ужитися з кількома. Тут може допомогти орієнтоване на аспекти програмування, але композиція (переміщення коду з attachBaseContext(Context base)і onResume()до окремого класу) може зробити трюк. Тоді все, що вам потрібно зробити, - це оголосити один об’єкт у кожному базовому класі діяльності та делегувати ці два виклики.
користувач905686

Якщо користувач змінить свою локальну мову, чи може бути змінена також і локалізація всіх попередніх сторінок активності?
Раджу вашПепе

Це найкраща відповідь на це питання. Дякую брате, це працює
Алок Гупта

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

Просто використовуйте цей допоміжний метод, щоб примусити конкретний локал.

ПОДРОБНЕ 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" - код країни.


Як зазначено в моїй посаді, 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 на фрагменти, адаптери тощо, де вам потрібен новий контекст.

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


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

-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();
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.