Locale returns to default

4

I am trying to change the locale of an app so that it is the user's choice through the following code

public static void updateLanguage(Context ctx) {
    SharedPreferencesManager sharedPreferencesManager = new SharedPreferencesManager(ctx);
    String lang = sharedPreferencesManager.readPreference(Constants.SHARED_PREFERENCES_LOCALE, "");
    if (StringUtils.isEmptyOrNull(lang)) {
        lang = Locale.getDefault().getLanguage();
    }
    setLanguage(ctx, lang);
}


@SuppressWarnings("deprecation")
public Locale getSystemLocaleLegacy(Configuration config) {
    return config.locale;
}

@TargetApi(Build.VERSION_CODES.N)
public Locale getSystemLocale(Configuration config) {
    return config.getLocales().get(0);
}

@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale) {
    config.locale = locale;
}

@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale) {
    config.setLocale(locale);
}

public static void setLanguage(Context context, String languageCode) {
    Locale locale = new Locale(languageCode);
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        setSystemLocale(config, locale);
    } else {
        setSystemLocaleLegacy(config, locale);
    }
    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}

Where I run the updateLanguage (this) method in the Application class.

I have several devices in which some works perfectly but in others the Locale.getDefault (). getLanguage () is set after few executions, although the sharedPreferences continues to define another. p>

For example, I have the device in Spanish and set the I want the app in English (in the configuration menu where I save the value in sharePreferences). Nothing else finished to set it, it works correctly, the application is displayed in English. But after some executions, the application is set in Spanish although the value of sharedPreferences remains in English.

Could someone tell me if I do something wrong or why some devices work correctly and others do not? (It also happens that in several devices of the same model reacts differently)

    
asked by Xose 29.11.2016 в 09:57
source

3 answers

1

I use the following code to change the language in the application, it is very similar to the following answer to a StackOverflow question in English and the one you have in your code.

public static void setLanguage (Activity activity, String idioma){
        try {
            Resources res = activity.getApplicationContext().getResources();
            DisplayMetrics dm = res.getDisplayMetrics();
            Configuration conf = res.getConfiguration();
            Locale locale = new Locale(idioma.toLowerCase());
            conf.locale = locale;
            Locale.setDefault(locale);
            res.updateConfiguration(conf, dm);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

Besides this you have to change the language in each Activity , as it says in the previous link.

  

And you have to set it every time you enter activity (each activity)   from my experience.

In each activity I get the language that I have saved or that the user has selected and then I call the previous function.

mPreferences = getSharedPreferences(Constants.nombrePreferencias, MODE_PRIVATE);
String idiomaGuardado = mPreferences.getString(Constants.pref_idioma, "es");

Utiles.setLanguage(this, idiomaGuardado);

I hope it helps you.

    
answered by 29.11.2016 в 10:46
1

The error may be that you do not detect the configuration change, where you must specify the language again.

@Override
public void onConfigurationChanged(Configuration newConfig) {

    Log.i(TAG, "onConfigurationChanged: " + newConfig.toString());

    super.onConfigurationChanged(newConfig);
    setLanguage(...,...);

}

I have encountered problems that sometimes work and others do not, when there is InstantRun activated. if you decide to deactivate it, remember to uninstall the app and reinstall it.

    
answered by 29.11.2016 в 15:03
1

If you save in SharedPreferences the configuration you have to ensure this is maintained, this within onConfigurationChanged() :

You define a global variable for the Locale:

 private Locale locale = null;

You get the value you previously saved by means of your methods:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      locale = getSystemLocale(config);
    } else {
      locale = setSystemLocaleLegacy(config);
    }

Implement the onConfigurationChanged() method to ensure you keep the Locale :

@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    if (locale != null)
    {
        newConfig.locale = locale;
        Locale.setDefault(locale);
        getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
    }
}
    
answered by 29.11.2016 в 17:22