Reputation: 225
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>
Upvotes: 9
Views: 4356
Reputation: 16587
I override my ConfigChange
in application like following and I call setLocale function each time configurationChanged
:
public class AioApplication extends Application {
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale(LocaleUtility.getLocale());
}
@Override
public void onCreate() {
super.onCreate();
LocaleUtility.initialize(this);
}
private void setLocale(Locale locale) {
Configuration conf = getBaseContext().getResources().getConfiguration();
conf.locale = locale;
getBaseContext().getResources().updateConfiguration(conf, getResources().getDisplayMetrics());
Configuration systemConf = Resources.getSystem().getConfiguration();
systemConf.locale = locale;
Resources.getSystem().updateConfiguration(systemConf, Resources.getSystem().getDisplayMetrics());
Locale.setDefault(locale);
}
}
Upvotes: 1
Reputation: 3485
It looks like your setLocale
updates the configuration of the app. But you've asked to handle that configuration change manually with android:configChanges="locale"
If you remove that line, your configuration change may work.
One thing I think you can remove is you onConfigurationChange
method from your application object. Does this not lead you down an infinite loop currently?
Update: looks like manually changing the locale configuration doesn't cause an activity restart. have a look at this: Changing Locale within the app itself
Although I'd be really careful about using android:configChanges
if you can
Upvotes: 0
Reputation: 181
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
Upvotes: 3