android locale right-to-left

Android context.getResources.updateConfiguration() en desuso



locale right-to-left (6)

Recientemente context.getResources (). updateConfiguration() ha quedado en desuso en la API 25 de Android y se recomienda usar el contexto. createConfigurationContext() lugar.

¿Alguien sabe cómo createConfigurationContext se puede utilizar para anular la configuración regional del sistema Android?

antes de que esto sea hecho por:

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


Aquí está la solución de @ bassel-mourjan con un poco de bondad de kotlin :):

import android.annotation.TargetApi import android.content.ContextWrapper import android.os.Build import java.util.* @Suppress("DEPRECATION") fun ContextWrapper.wrap(language: String): ContextWrapper { val config = baseContext.resources.configuration val sysLocale: Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { this.getSystemLocale() } else { this.getSystemLocaleLegacy() } if (!language.isEmpty() && sysLocale.language != language) { val locale = Locale(language) Locale.setDefault(locale) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { this.setSystemLocale(locale) } else { this.setSystemLocaleLegacy(locale) } } return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { val context = baseContext.createConfigurationContext(config) ContextWrapper(context) } else { baseContext.resources.updateConfiguration(config, baseContext.resources.displayMetrics) ContextWrapper(baseContext) } } @Suppress("DEPRECATION") fun ContextWrapper.getSystemLocaleLegacy(): Locale { val config = baseContext.resources.configuration return config.locale } @TargetApi(Build.VERSION_CODES.N) fun ContextWrapper.getSystemLocale(): Locale { val config = baseContext.resources.configuration return config.locales[0] } @Suppress("DEPRECATION") fun ContextWrapper.setSystemLocaleLegacy(locale: Locale) { val config = baseContext.resources.configuration config.locale = locale } @TargetApi(Build.VERSION_CODES.N) fun ContextWrapper.setSystemLocale(locale: Locale) { val config = baseContext.resources.configuration config.setLocale(locale) }

Y así es como lo usas:

override fun attachBaseContext(newBase: Context?) { super.attachBaseContext(ContextWrapper(newBase).wrap(defaultLocale.language)) }



Inspirado por Calligraphy, Mourjan y yo, creé esto.

primero debe crear una subclase de Aplicación:

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()); } } }

entonces necesita configurar esto en su etiqueta de aplicación AndroidManifest.xml:

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

y agregue esto a su etiqueta de actividad AndroidManifest.xml.

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

tenga en cuenta que pref_locale es un recurso de cadena como este:

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

y el código rígido "en" es el idioma predeterminado si pref_locale no está configurado


Inspirado por la Calligraphy , terminé creando un contenedor de contexto. En mi caso, necesito sobrescribir el idioma del sistema para proporcionar a los usuarios de mi aplicación la opción de cambiar el idioma de la aplicación, pero esto se puede personalizar con cualquier lógica que necesite implementar.

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); } }

e inyectar su envoltorio, en cada actividad agregue el siguiente código:

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

ACTUALIZACIÓN 19/10/2018 A veces, después del cambio de orientación, o la actividad pausa / reanuda, el objeto de configuración se restablece a la configuración predeterminada del sistema y, en consecuencia, veremos que la aplicación muestra el texto en inglés "en" a pesar de que envolvemos el contexto con la configuración regional francesa "fr" . Por lo tanto, y como una buena práctica, nunca retenga el objeto Context / Activity en una variable global en actividades o fragmentos.

además, cree y use lo siguiente en un MyBaseFragment o MyBaseActivity:

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

Esta práctica le proporcionará una solución 100% libre de errores.


Probablemente así:

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

Bonificación: un artículo de blog que usa createConfigurationContext ()


Prueba esto:

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