I have two languages in my app, English and Dutch. In preferences you are able to change the language, which works after a restart of the app. But when the user opens the app for the very first time, the default language which has been set in the following code is not being used (R.xml.user_settings). It uses the device language (which is Dutch is my case).
<ListPreference
android:defaultValue="@string/pref_languages_default"
android:entries="@array/languages"
android:entryValues="@array/listValues"
android:key="language"
android:title="@string/languages" />
Where "@string/pref_languages_default", "@array/languages", and "@array/listValues" are:
<string translatable="false" name="pref_languages_default">en</string>
<string-array name="languages">
<item name="nl">Dutch</item>
<item name="en">English</item>
</string-array>
<string-array name="listValues">
<item name="nl">nl</item>
<item name="en">en</item>
</string-array>
In MyApplication.java I have the following code:
public class MyApplication extends Application {
private Locale locale = null;
@Override
public void onCreate() {
PreferenceManager.setDefaultValues(this, R.xml.user_settings, false);
super.onCreate();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Configuration config = getBaseContext().getResources().getConfiguration();
String lang = settings.getString("LANG", "");
if (!"".equals(lang) && !config.locale.getLanguage().equals(lang)) {
locale = new Locale(lang);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
}
And the code in SettingsFragment.java (where I can select the language):
public class SettingsFragment extends PreferenceFragment {
Locale myLocale;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.user_settings);
ListPreference langPref = (ListPreference) findPreference("language");
langPref.setSummary(langPref.getEntry());
langPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
preference.setSummary(o.toString());
return true;
}
});
ListPreference langPreference = (ListPreference) findPreference("language");
langPreference.setOnPreferenceChangeListener(languageChangeListener);
}
Preference.OnPreferenceChangeListener languageChangeListener = new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
switch (newValue.toString()) {
case "nl":
PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()).edit().putString("LANG", "nl").commit();
setLocale("nl");
Toast.makeText(getActivity().getBaseContext(), R.string.save_language_changes, Toast.LENGTH_LONG).show();
break;
case "en":
PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()).edit().putString("LANG", "en").commit();
setLocale("en");
Toast.makeText(getActivity().getBaseContext(), R.string.save_language_changes, Toast.LENGTH_LONG).show();
break;
/*default:
PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()).edit().putString("LANG", "en").commit();
setLocale("en");
Toast.makeText(getActivity().getBaseContext(), R.string.save_language_changes, Toast.LENGTH_LONG).show();
break;*/
}
return true;
}
};
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
Locale.setDefault(myLocale);
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
}
}
The thing is, the ListPreference summary correctly shows the default language, however, the default language has not been set. How can I get the app to show the correct language? I have a values and values-nl directory with the correct strings.
At first run of the app the SharedPreferences
has no value for the LANG
key so the line String lang = settings.getString("LANG", "");
sets tha lang
to ""
and you change the local only if lang
not empty.
So for that you need the default value to be one of the languages you use in the app.
And to do that simply change the line
String lang = settings.getString("LANG", "");
to
String lang = settings.getString("LANG", "en");
or
String lang = settings.getString("LANG", "nl");