102 votes

Android context.getResources.updateConfiguration () obsolète

Tout récemment contexte.getResources().updateConfiguration() a été déprécié dans l'API Android 25 et il est conseillé d'utiliser le contexte.createConfigurationContext() à la place.

Personne ne sait comment createConfigurationContext peuvent être utilisés pour remplacer les paramètres régionaux du système android?

avant cela serait fait par:

Configuration config = getBaseContext().getResources().getConfiguration();
config.setLocale(locale);
context.getResources().updateConfiguration(config,
                                 context.getResources().getDisplayMetrics());

135voto

Bassel Mourjan Points 111

Inspiré par la Calligraphie, j'ai fini par créer un wrapper de contexte. Dans mon cas, j'ai besoin de remplacer le système de la langue de fournir à mes utilisateurs de l'application avec la possibilité de changer d'application de la langue, mais ce qui peut être personnalisé avec toute la logique que vous avez besoin de mettre en œuvre.

    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.ContextWrapper;
    import android.content.res.Configuration;
    import android.os.Build;

    import java.util.Locale;

    public class MyContextWrapper extends ContextWrapper {

    public MyContextWrapper(Context base) {
        super(base);
    }

    @SuppressWarnings("deprecation")
    public static ContextWrapper wrap(Context context, String language) {
        Configuration config = context.getResources().getConfiguration();
        Locale sysLocale = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sysLocale = getSystemLocale(config);
        } else {
            sysLocale = getSystemLocaleLegacy(config);
        }
        if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                setSystemLocale(config, locale);
            } else {
                setSystemLocaleLegacy(config, locale);
            }

        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
             context = context.createConfigurationContext(config);
        } else {
             context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
            }
        return new MyContextWrapper(context);
    }

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

    @TargetApi(Build.VERSION_CODES.N)
    public static 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);
    }
}

et pour injecter votre enveloppe, dans chaque activité, ajoutez le code suivant:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(MyContextWrapper.wrap(newBase,"fr"));
}

Mise à JOUR 10/19/2018 Parfois, après un changement d'orientation, ou de l'activité mettre en pause/reprendre la Configuration de l'objet se remet à défaut de la Configuration du système et dans la suite, nous verrons l'application de l'affichage en anglais "fr" texte même si nous avons terminé le contexte français "fr" locale. Par conséquent, et comme une bonne pratique, ne jamais conserver le Contexte/l'Activité de l'objet dans une variable globale dans des activités ou des fragments.

en outre, de créer et d'utiliser les éléments suivants dans un MyBaseFragment ou MyBaseActivity:

public Context getMyContext(){
    return MyContextWrapper.wrap(getContext(),"fr");
}

Cette pratique va vous fournir 100% sans bug solution.

41voto

compte14031879 Points 1023

Probablement comme ça:

 Configuration overrideConfiguration = getBaseContext().getResources().getConfiguration();
overrideConfiguration.setLocales(LocaleList);
Context context  = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();
 

Bonus: un article de blog qui utilise createConfigurationContext ()

6voto

Mahpooya Points 331

Inspiré par la Calligraphie & Mourjan et moi-même, j'ai créé cette.

vous devez d'abord créer une sous-classe de la Demande:

public class MyApplication extends Application {
    private Locale locale = null;

    @Override
    public void onCreate() {
        super.onCreate();

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);

        Configuration config = getBaseContext().getResources().getConfiguration();

        String lang = preferences.getString(getString(R.string.pref_locale), "en");
        String systemLocale = getSystemLocale(config).getLanguage();
        if (!"".equals(lang) && !systemLocale.equals(lang)) {
            locale = new Locale(lang);
            Locale.setDefault(locale);
            setSystemLocale(config, locale);
            updateConfiguration(config);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (locale != null) {
            setSystemLocale(newConfig, locale);
            Locale.setDefault(locale);
            updateConfiguration(newConfig);
        }
    }

    @SuppressWarnings("deprecation")
    private static Locale getSystemLocale(Configuration config) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return config.getLocales().get(0);
        } else {
            return config.locale;
        }
    }

    @SuppressWarnings("deprecation")
    private static void setSystemLocale(Configuration config, Locale locale) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            config.setLocale(locale);
        } else {
            config.locale = locale;
        }
    }

    @SuppressWarnings("deprecation")
    private void updateConfiguration(Configuration config) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            getBaseContext().createConfigurationContext(config);
        } else {
            getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
        }
    }
}

ensuite, vous devez définir à votre AndroidManifest.xml balise application:

<application
    ...
    android:name="path.to.your.package.MyApplication"
    >

et l'ajouter à votre AndroidManifest.xml l'activité de la balise.

<activity
    ...
    android:configChanges="locale"
    >

notez que pref_locale est une ressource de chaîne comme ceci:

<string name="pref_locale">fa</string>

et coder en dur "fr" est par défaut lang si pref_locale n'est pas placé

0voto

Il existe une solution simple avec contextWrapper ici: Android N change de langue par programme Prêtez attention à la méthode recreate ()

-1voto

Eric B. Points 3673

Essaye ça:

 Configuration config = getBaseContext().getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X