I have an Android application with English strings in values/strings.xml. For each string in that file, I have an entry in values-ja/strings.xml with the Japanese translation of that string. If I set the emulator, a Nexus One or Nexus S to Japanese, the UI shows Japanese text throughout. Most of the time.
Sometimes, some portion of the UI will appear in English, even though the current locale is ja-JP. For instance, I wrote this test code in the onCreate() method of one of my activities:
Log.e(TAG, "Default locale = '" + Locale.getDefault().toString() + "'");
Log.e(TAG, "My string = '" + getResources().getString(R.string.my_string) + "'");
Sometimes I will see in LogCat:
Default locale is 'ja_JP'
My string is '日本'
Other times I will see:
Default locale is 'ja_JP'
My string is 'English'
Sometimes this issue is resolved by rotating the phone. Sometimes it's resolved by exiting and restarting the app. Sometimes only a portion of a single screen is in English. Sometimes this issue occurs with strings that are pulled out of the resources via code, and sometimes it occurs with strings that are only referenced by a layout. Nowhere in my application do I call Locale.setDefault(), so that's not causing the issue.
UPDATE
I've found a way to correct the issue for a specific activity. In that activity's onCreate():
Log.e(TAG, "getString: '" + getString(R.string.my_string) + "'");
Log.e(TAG, "getResources().getConfiguration(): '" +
getResources().getConfiguration().toString() + "'");
Log.e(TAG, "getResources().getDisplayMetrics(): '" +
getResources().getDisplayMetrics().toString() + "'");
Log.e(TAG, "Setting configuration to getConfiguration()");
getResources().updateConfiguration(getResources().getConfiguration(),
getResources().getDisplayMetrics());
Log.e(TAG, "getString: '" + getString(R.string.my_string) + "'");
Log.e(TAG, "getResources().getConfiguration(): '" +
getResources().getConfiguration().toString() + "'");
Log.e(TAG, "getResources().getDisplayMetrics(): '" +
getResources().getDisplayMetrics().toString() + "'");
This results in the following in LogCat:
getString: 'English'
getResources().getConfiguration(): '{ scale=1.0 imsi=0/0 loc=ja_JP touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=8}'
getResources().getDisplayMetrics(): 'DisplayMetrics{density=1.5, width=480, height=800, scaledDensity=1.5, xdpi=254.0, ydpi=254.0}'
Setting configuration to getConfiguration()
getString: '日本'
getResources().getConfiguration(): '{ scale=1.0 imsi=0/0 loc=ja_JP touch=3 keys=1/1/2 nav=3/1 orien=1 layout=34 uiMode=17 seq=8}'
getResources().getDisplayMetrics(): 'DisplayMetrics{density=1.5, width=480, height=800, scaledDensity=1.5, xdpi=254.0, ydpi=254.0}'
As you can see from the log, nothing in the current configuration changes, but getString() gives different results.
It's impractical to use this workaround in every place in my application where a resource might be used, but hopefully this provides a hint about what's going wrong.
Are you changing Locale while the application is running? If so, have you properly implemented the various elements of the Activity lifecycle (including
onSaveInstanceState()
andonRestoreInstanceState()
)?According to http://developer.android.com/guide/topics/resources/runtime-changes.html, a change in configuration at runtime should cause the Activity to be destroyed & restarted. It sounds like your app is noticing the new configuration but is not restarting properly (until restarting the whole App, or changing orientation).
Are you doing anything funky in
onSaveInstanceState
oronDestroy
?P.s. If it corrects itself only on certain orientation changes, can you advise if those orientation changes occur on layouts that have different vertical & horizontal layout files?