Reputation: 73433
I want to have a configurable language settings in my app.
So, in onCreate of my activity, I call Resources.updateConfiguration with the new locale.
However, after onCreate (at some time, I can't find it when), the locale is set back to the default locale.
On the code example below, the strings shown in the main layout (as inflated by setContentView) shows the "in" language version, BUT when I press the menu button, on which onCreateMenu is called, the strings is taken from the "en" (default) locale.
The log shows this:
18337 oncreate D { scale=1.0 imsi=525/1 loc=intouch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=143}
30430 ActivityManager I Displayed activity yuku.coba.locale/.CobaLocaleActivity: 266 ms (total 266 ms)
18337 KeyCharacterMap W No keyboard for id 65540
18337 KeyCharacterMap W Using default keymap: /system/usr/keychars/qwerty.kcm.bin
18337 onmenu D { scale=1.0 imsi=525/1 loc=en_GB touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=143}
Between "oncreate" and "onmenu", the locale magically changes.
Please help, I have been tinkering with this with no luck.
Code snippet:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Configuration c = new Configuration();
c.locale = new Locale("in");
getResources().updateConfiguration(c, null);
setContentView(R.layout.main);
Log.d("oncreate", getResources().getConfiguration().toString());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d("onmenu", getResources().getConfiguration().toString());
new MenuInflater(this).inflate(R.menu.utama, menu);
return true;
}
Upvotes: 1
Views: 6003
Reputation: 3591
You can use a method I wrote, to handle this situation:
/**
* Sets app language locale also taking account system resets of the Locale; Resetting of the Locale is done right after onResume of the first Activity that is run in the application.
* So... if the AppLanugage is set e.g. in first activitys onCreate method, this language will be reset shortly after; To counter this the method starts the Timer (if a flag is set) to
* handle pottential Locale resets that are done by the system.
*
* In case the flag alsoReloadAfterDelay is set, usually the numberOfResetsOsDoes parameter and the numberOfResetsOsDoes should be used separately from eachother; Either the timer
* shoudl run till the numberOfResetsOsDoes is matched, or run till the timer runs out of time, irrespectively of the number of resets the os does
* @param appContext The application context
* @param lang New language to set the locale
* @param alsoReloadAfterDelay The flag that says whether to start a timer that will handle pottential Locale resets, that are done by Android OS;
* @param numberOfResetsOsDoes The number of resets the OS does after onResume method of the first activity; So far I noticed that it is happening twice (emulator 2.3.3)
* @param resetTimerDuration The duration of the reset timer;
* @see <a href="https://groups.google.com/forum/?hl=en#!topic/android-developers/VEAWMCdyIWg">https://groups.google.com/forum/?hl=en#!topic/android-developers/VEAWMCdyIWg</a>
* @return True if the operation succeded (if the given lang param was appliable for instance); False otherwise
*/
public static boolean setAppLanguageLocale(final Context appContext, final String lang, boolean alsoReloadAfterDelay, final int numberOfResetsOsDoes, int resetTimerDuration)
{
final String previousAppLanguage = getAppLanguage(appContext);
final String newLang = lang.toUpperCase(Locale.US);
if(previousAppLanguage.equals(newLang))
return true;
setAppLanguageLocaleP(appContext, lang);
if(alsoReloadAfterDelay)
{
new CancellableCountDownTimer(resetTimerDuration, 10)
{
private int aResetCounter = 0;
@Override
public void onTick(long millisUntilFinished)
{
if(aResetCounter == numberOfResetsOsDoes)
{
this.cancel();
return;
}
String currentAppLanguage = getAppLanguage(appContext);
if(!currentAppLanguage.equals(newLang))
{
aResetCounter++;
setAppLanguageLocale(appContext, lang);
}
}
@Override
public void onFinish()
{
}
}.start();
}
return true;
}
Upvotes: 0
Reputation: 10938
instead of getResources().updateConfiguration(c, null);
try getBaseContext().getResources().updateConfiguration(c, null);
(not getDefaultContext sorry)
Upvotes: 0
Reputation: 68474
I advice not force locale to something that is different from the device setting. You will run into the problems. You can move your call to onResume. It will be better, but still you're gonna fight device configuration. Again. Don't do this .
Upvotes: 0