Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android language changes after rotation

When my app is installed, on first run it asks user to choose language; But if user starts app on second time, language is set automatically (to previously selected one).

Problem is that, on first run when user selects language, app still is in English (no matter what language user selects), but if I rotate device, then language is changed to correct one (to selected one). Same problem occurs on apps second run; App starts in English, but after rotation language is changed to correct one.

Any suggestions? thank you in advance

here code from MainActivity from where I change language:

private void initApp() {
        if (Settings.getLanguage().equals("")){ 
            String[] items = { getResources().getString(R.string.lang_eng), getResources().getString(R.string.lang_geo)};
            showDialogSingleChoise(items, getResources().getString(R.string.select_language_title), 0, false, false, this.languageSelectedListener, this.languageConfirmedListener, null);
        } else {        
            System.out.println("initApp: " + Settings.getLanguage());

            Settings.setLanguage(MainActivity.this.getResources(), Settings.getLanguage());
            appVersionCheck();
        }
    }

private OnClickListener languageConfirmedListener = new OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {
        Settings.setLanguage(MainActivity.this.getResources(), MainActivity.this.language);
        appVersionCheck();
    }
};

and here is code fragment from settings:

public static void setLanguage(Resources res, String langString){
        System.out.println("lang in pref: " + langString);
        setStringProperty(PREFS_LANG ,langString);
        MainApp.getInstance().setLocale(res);
    }

Here is my Application class:

public class MainApp extends Application {
    private static volatile MainApp instance;

    public static MainApp getInstance() {
        return MainApp.instance;
    }

    @Override
    public void onCreate() {
        MainApp.instance = this;
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale(this.getResources());
    }

    public void setLocale(Resources res) {
        System.out.println("initApp: " + Settings.getLanguage() == "" ? Settings.LANG_EN : Settings.getLanguage());
        Configuration conf = res.getConfiguration();
        conf.locale = new Locale(Settings.getLanguage() == "" ? Settings.LANG_EN : Settings.getLanguage());
        res.updateConfiguration(conf, res.getDisplayMetrics());
    }
}

and lastly, this is manifest (do I need android:configChanges="locale" at all?):

<application
        android:name="...MainApp"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="....MainActivity"
            android:configChanges="locale"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
like image 229
Giorgi Margiani Avatar asked Sep 26 '22 07:09

Giorgi Margiani


1 Answers

Your configuration cannot be applied until your Activity is restarted,so when you click to change locale it cannot be applied at once,but when you rotate your screen the Activity restarts thus applies your configuration changes.

You should restart your Activity manually after click to change the locale,and here is a code demo to restart your Activity:

private void restartActivity() {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
    }

And I think you should not write the changing locale code in your Application class,it should be written in the Activity that you use to change locale.

As for applying new locale in the future app opening,you can use SharedPreferences to save your configuration and get the locale value every time your application is opened and apply it.

You can get the SharedPreferences and apply the locale in the Application class's onCreate() method.

And you certainly should write the android:configChanges="locale|orientation" in your manifest and the onConfigurationChanged() method is also necessary.Because if you rotate the screen or do anything else that change the system configuration that can restart your Activity,the default locale will be applied.So you should make sure the new locale is applied every time the configuration is changed.

For more details about how to deal with locale change,you can read this: How to refresh activity after changing language (Locale) inside application

like image 166
SamMao Avatar answered Sep 30 '22 06:09

SamMao