Невозможно изменить язык приложения, используя createConfigurationContext()

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

private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Resources res = context.getResources();
    Configuration config = new Configuration(res.getConfiguration());
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        config.setLocale(locale);
        LocaleList.setDefault(new LocaleList(locale));

        context = context.createConfigurationContext(config);
    }
    else if (Build.VERSION.SDK_INT >= 17) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
    return context;
}

Чем я переопределяю Application а также Activity"s attachBaseContext()

protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleManager.setLocale(base));
}

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

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

Любая помощь будет оценена.

РЕДАКТИРОВАТЬ

Оказалось, что проблема была в том, что у меня была строка resConfigs "en" в build.gradle, которая предотвращала изменение языка.

1 ответ

Выберите Langauge Activity

private LinearLayout llHindi, llEnglish;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_change_language);
    resetTitles();
    llHindi = (LinearLayout) findViewById(R.id.llHindi);
    llEnglish = (LinearLayout) findViewById(R.id.llEnglish);


    llHindi.setOnClickListener(this);
    llEnglish.setOnClickListener(this);
}



private boolean setNewLocale(String language, boolean restartProcess) {
    LocaleManager.setNewLocale(this, language);

    Intent i = new Intent(this, MainActivity.class);
    startActivity(i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK));

    if (restartProcess) {
        System.exit(0);
    } else {
    }
    return true;
}



@Override
public void onClick(View v) {
    int id = v.getId();

    if (id == R.id.llEnglish) {
        setNewLocale(LANGUAGE_ENGLISH, true);
    }

    if (id == R.id.llHindi) {
        setNewLocale(LANGUAGE_HINDI, true);
    }
}



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



private void resetTitles() {
    try {
        ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), GET_META_DATA);
        if (info.labelRes != 0) {
            setTitle(info.labelRes);
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
}

LocaleManager

public class LocaleManager {

public static final  String LANGUAGE_ENGLISH   = "en";
public static final  String LANGUAGE_HINDI = "hi";
private static final String LANGUAGE_KEY       = "language_key";

public static Context setLocale(Context c) {
    return updateResources(c, getLanguage(c));
}

public static Context setNewLocale(Context c, String language) {
    persistLanguage(c, language);
    return updateResources(c, language);
}

public static String getLanguage(Context c) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
    return prefs.getString(LANGUAGE_KEY, LANGUAGE_ENGLISH);
}

@SuppressLint("ApplySharedPref")
private static void persistLanguage(Context c, String language) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
    // use commit() instead of apply(), because sometimes we kill the application process immediately
    // which will prevent apply() to finish
    prefs.edit().putString(LANGUAGE_KEY, language).commit();
}

private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Resources res = context.getResources();
    Configuration config = new Configuration(res.getConfiguration());
    if (Build.VERSION.SDK_INT >= 17) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
    return context;
}

public static Locale getLocale(Resources res) {
    Configuration config = res.getConfiguration();
    return Build.VERSION.SDK_INT >= 24 ? config.getLocales().get(0) : config.locale;
}

глобальный класс расширяет приложение

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(LocaleManager.setLocale(base));
    //Log.d(TAG, "attachBaseContext");
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    LocaleManager.setLocale(this);
    //Log.d(TAG, "onConfigurationChanged: " + newConfig.locale.getLanguage());
}

это будет работать, и вам нужно создать другой файл string.xml для другого языка

Другие вопросы по тегам