I have implemented custom locale selection about a year ago but after 4.1 release users start to complain on constant activity blinking. Here is code I'm using (compiled from different SO answers):
public final class TestApplication extends Application
{
private Locale desiredLocale = new Locale("ru-RU");
#Override
public void onCreate() {
super.onCreate();
updateLocale(new Configuration());
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
updateLocale(newConfig);
}
private void updateLocale(Configuration newConfig) {
newConfig.locale = desiredLocale;
Locale.setDefault(desiredLocale);
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
}
}
Application contains only one empty activity, which is recreated by Android every second after I change device orientation. Here is the source of sample.
It looks like all applications which use this technique became invalid. What is the correct approach?
This line caused solution to fail:
getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
Correct (at least it works) implementation is defined here
https://stackoverflow.com/a/14010044/554336 :
Configuration config = new Configuration();
config.locale = locale;
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
So new configuration instance should be created every time.
Related
I am working with google map in my activity.
When i change language for example Chinese in my app settings
the langauge of map did not change till i reopen my app.
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.activity_maps);
i searched a lot about this issue i found that it is google map caching issue but did not found any solution.
I can think about 2 options to solve this:
Calling setContentView in the onConfigurationChanged method
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (language_changed){//pseudo_code
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.activity_maps);
//now you need to do again all the findViewById call
}
}
Restart the activity in the onConfigurationChanged method
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (language_changed){//pseudo_code
startActivity(CurrentActivity.this, CurrentActivity.class);
finish();
}
}
I've not tested this, but maybe it's a starting point to try to solve your problem.
Don't forget to add android:configChanges="locale" to your activity tag in the AndroidManifest.xml to let the system know that you want to handle Locale changes by yourself. Read more here if needed
You can use BroadcastReceiver with LOCALE_CHANGED Intent to detect setting change, and then update your view (Map view or total layout).
https://developer.android.com/reference/android/content/Intent.html#ACTION_LOCALE_CHANGED
public class LocaleReceiver extends BroadcastReceiver {
public LocaleReceiver() {}
#Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())){
// Call a method to trigger view refreshing here
}
}
}
after studying about supporting multiple languages in android application, i have good the basic idea about how i can make resources for different languages within application, for example i want to add Spanish language in my application so in res direction within my application i have added values-en directory and in that direct i have added strings resource and within that resource i have added strings with values of Spanish text, in my application default language is English now i want to know how can i switch it to Spanish, i have the resources ready i just need to change my application language to Spanish
Use below code in your onCreate() after setContentView:
String languageToLoad = "es";
Locale locale = new Locale(languageToLoad);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
You also have to change your value folder to values-es. values-en is for English. Hope this helps.
To change App locale follow below code:
1) Create LocaleUtils class:
public class LocaleUtils {
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if (sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
// We must use the now-deprecated config.locale and res.updateConfiguration here,
// because the replacements aren't available till API level 24 and 17 respectively.
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
2) In Application Class:
public class YourAppName extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("es"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
3) Remember, Your Application class name and <application android:name=".YourAppName"> should be same. Otherwise it won't work. Kudos to this answer.
I am currently work with changing language in the app. My app structure is tab host + fragment I have successfully change the locale but it is quite strange.
That means after I run the change locale code , it does not change the view immediately but only when I go to another tab. I think this is due to I need to reload the view, but are there any way to implment this without kill and restart the activity?
Because there is some goolge analytic code, the entry number will be increase if the user start activity again? Are there standard way to reload view? thanks
The change locale function is in one of the tabhost fragment, I have to refresh the view in tabhost (main activity), and the current fragment .
public OnClickListener setChangeLangListener(final String lang) {
OnClickListener changeLangListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
Configuration config = new Configuration(getResources()
.getConfiguration());
if (lang.equals("en")) {
config.locale = Locale.ENGLISH;
chi.setTextColor(oldColor);
eng.setTextColor(getActivity().getResources().getColor(android.R.color.white));
} else {
config.locale = Locale.TRADITIONAL_CHINESE;
eng.setTextColor(oldColor);
chi.setTextColor(getActivity().getResources().getColor(android.R.color.white));
}
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
}
};
return changeLangListener;
}
eng.setOnClickListener(setChangeLangListener("en"));
chi.setOnClickListener(setChangeLangListener("zh"));
Allright add this to your manifest
android:configChanges="locale"
and override onConfigurationChanged() in your activity
#Override
public void onConfigurationChanged(Configuration newConfig) {
// refresh your views here
super.onConfigurationChanged(newConfig);
}
go here for more info.
Hope it helps. :)
Have you tried calling setContentView. Eg.:
String languageToLoad = "fr"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
activity.setContentView(R.layout.your_layout);
I'm developing an application for android and when everything should be finished I've found an extrange behaviour. In some devices the screen starts to flicker, and there is no apparent reason for that. It may happen in initial splash with only an AsyncTask quering a webservice or in the home screen with no asynctask at all.
It's strange because only happens in devices with android 4.2, nor in 2.3 or 2.2. I've tried enabling the tag harware-accelration in manifest but I've no clue for what can be the reason
Some help?
Thanks in advance.
Finally I've managed how to avoid this. Here was the trick, just changing my Application's Override OnConfigurationChanged.
This was my old code
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Locale l = getLocale();
Configuration config = new Configuration(newConfig); // get Modifiable Config from actual config changed
config.locale = l;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
and I've changed to this
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Locale l = getLocale();
Configuration config = new Configuration(newConfig); // get Modifiable Config from actual config changed
config.locale = l;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
I hope someone finds this useful.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Changing Locale within the app itself
in my application I need to "force" language let's say that I have locale in english as default polish and finnish, according to that post I had created function posted also bellow, function is called in createActivity(), but the problem is it does not work.... any idea why? Any suggestions?
private void setLocale(String localeCode){
Locale locale = new Locale(localeCode);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
Here is what I got so far. I know this question is resolved, but my solution is easier and more compact. No other changes are needed, no android:configurationChanges attribute for all activities in your manifest.
public class SigmaMiddleEastApplication extends PPGApplication {
#Override
public void onConfigurationChanged(Configuration newConfig) {
newConfig.locale = Locale.ENGLISH;
super.onConfigurationChanged(newConfig);
Locale.setDefault(newConfig.locale);
getBaseContext().getResources().updateConfiguration(newConfig, getResources().getDisplayMetrics());
}
}
BEWARE this may cause problems:
What could cause an Android activity to relaunch itself infinitely when returning from camera?
Add the following in the manifest (for every activity) :
android:configChanges="locale"