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

Я создал двуязычный (с двумя языками) приложение для Android. Я вставил свои строки ресурсов в два файла:

For Persian language (default)
values/strings_locale.xml‬

For English language 
values-en/strings_locale.xml‬

В моем первом запуске Activity я вставил следующий код:

Configuration c = new Configuration(this.getResources().getConfiguration());
c.locale = new Locale("fa_IR");

this.getResources().updateConfiguration(c, this.getResources().getDisplayMetrics());

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

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

Почему это происходит и как я могу решить эту проблему?

Ответ 1

Вы можете создать класс, который расширяет Application. Там вы можете переопределить один метод, который вызывается каждый раз при изменении конфигурации (пример, когда меняется ориентация экрана).

Что-то вроде:

public class MyApplication extends Application {
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale();
    }

    private void setLocale() {
        Locale locale = new Locale("fa_IR");
        Locale.setDefault(locale);
        Configuration config = new Configuration();
        config.locale = locale;
        getBaseContext().getResources().updateConfiguration(config,
              getBaseContext().getResources().getDisplayMetrics());
    }
}

И не забудьте объявить его в манифесте: пример класса приложения

В AndroidManifest.xml:

<application
    android:name="com.blaablaa.bumbam.MyApplication"
    ...

Ответ 2

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

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

Ответ 3

Вы можете создать пользовательский ContextWrapper

public class mContextWrapper extends ContextWrapper {
    public mContextWrapper(Context base){
        super(base);
    }

    @SuppressWarnings("deprecation")
    public static ContextWrapper wrap(Context context, String language) {
        Configuration config = context.getResources().getConfiguration();
        Locale sysLocale = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sysLocale = getSystemLocale(config);
        } else {
            sysLocale = getSystemLocaleLegacy(config);
        }
        if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                setSystemLocale(config, locale);
            } else {
                setSystemLocaleLegacy(config, locale);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                context = context.createConfigurationContext(config);
            } else {
                context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
            }
        }
        return new mContextWrapper(context);
    }

    @SuppressWarnings("deprecation")
    public static Locale getSystemLocaleLegacy(Configuration config){
        return config.locale;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static Locale getSystemLocale(Configuration config){
        return config.getLocales().get(0);
    }

    @SuppressWarnings("deprecation")
    public static void setSystemLocaleLegacy(Configuration config, Locale locale){
        config.locale = locale;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static void setSystemLocale(Configuration config, Locale locale){
        config.setLocale(locale);
    }
}

и в вашей активности attachBaseContext присоедините свой собственный ContextWrapper

 @Override
    protected void attachBaseContext(Context newBase) {
        globalClass = (YouAppClass)newBase.getApplicationContext();
        //try geting the lang you have setted inside your YouAppClass class
        // or you can use shared preferences for it 
        //pref = PreferenceManager.getDefaultSharedPreferences(newBase)
        lang=globalClass .getLang();
        super.attachBaseContext(mContextWrapper.wrap(newBase,lang));
    }