java - samsung - Cómo cambiar el idioma de la aplicación Android O/Oreo/api 26
api de android oreo (8)
Quiero cambiar el idioma de la aplicación y esto funciona bien hasta la API 26.
Para api> 25 pongo Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
antes de setContentView(R.layout.activity_main);
pero nada cambia.
Los docs no explican mucho sobre esto.
Después de usar toda la solución en todas las fuentes, finalmente encontré mi problema. Eso me hace enojar por 2 días.
Todo el mundo sabe que en Android Oreo (API 26) debemos usar createConfigurationContext
, pero mi problema es usar el nombre del país con el local.
Reemplazar
en_US con en
ar_AE con ar
fa_IR con fa
Y mi problema resuelto.
Espero ayudar a alguien
Es posible, sin embargo, no recomendaría configurar el idioma programáticamente
Android está diseñado para que la interfaz de usuario del sistema y su aplicación tengan el mismo idioma . Si lo cambia programáticamente, estará luchando contra el sistema.
En su lugar, lo que puede hacer es habilitar el soporte multilenguaje agregando diferentes cadenas de idiomas.xml, esto cambiará el idioma automáticamente
Recomiendo leer este artículo de Google Developers :
Apoyando diferentes idiomas y culturas
Si realmente necesita cambiarlo programáticamente puede hacer lo siguiente
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
En SDK> = 21, debe llamar a ''Resources.updateConfiguration ()'' , de lo contrario los recursos no se actualizarán.
Espero eso ayude.
Sí, en Android, la localización de Oreo no funciona bien con la configuración de actualización. Pero está en desuso en el propio android n. En lugar de la configuración de actualización, use createconfiguration en cada archivo adjunto. Está funcionando bien para mí. Prueba esto...
En tu actividad agrega esto ..
@Override
protected void attachBaseContext(Context newBase) {
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
super.attachBaseContext(MyContextWrapper.wrap(newBase, "ta"));
}
else {
super.attachBaseContext(newBase);
}
}
En MyContextWrapper.java
public static ContextWrapper wrap(Context context, String language) {
Resources res = context.getResources();
Configuration configuration = res.getConfiguration();
Locale newLocale = new Locale(language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocale(newLocale);
LocaleList localeList = new LocaleList(newLocale);
LocaleList.setDefault(localeList);
configuration.setLocales(localeList);
context = context.createConfigurationContext(configuration);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(newLocale);
context = context.createConfigurationContext(configuration);
} else {
configuration.locale = newLocale;
res.updateConfiguration(configuration, res.getDisplayMetrics());
}
return new ContextWrapper(context);
}
Tuve el mismo problema: desde Android 8.0+, algunas partes de mi aplicación ya no cambiaron su idioma. La actualización del contexto tanto de la aplicación como de la actividad me ayuda. Aquí hay un ejemplo de la función MainActivity:
private void setApplicationLanguage(String newLanguage) {
Resources activityRes = getResources();
Configuration activityConf = activityRes.getConfiguration();
Locale newLocale = new Locale(newLanguage);
activityConf.setLocale(newLocale);
activityRes.updateConfiguration(activityConf, activityRes.getDisplayMetrics());
Resources applicationRes = getApplicationContext().getResources();
Configuration applicationConf = applicationRes.getConfiguration();
applicationConf.setLocale(newLocale);
applicationRes.updateConfiguration(applicationConf,
applicationRes.getDisplayMetrics());
}
getApplicationContext()
usar getApplicationContext()
lugar de getContext()
updateConfiguration
está en desuso y debe usar createConfigurationContext
. Lo resolví de esta manera:
@Override
protected void attachBaseContext(Context newBase) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Configuration config = newBase.getResources().getConfiguration();
//Update your config with the Locale i. e. saved in SharedPreferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase);
String language = prefs.getString(SP_KEY_LANGUAGE, "en_US");
Locale.setDefault(locale);
config.setLocale(new Locale(language));
newBase = newBase.createConfigurationContext(config);
}
super.attachBaseContext(newBase);
}
Actualizado para todas las versiones de Android hasta Oreo
Crea una clase como esta
public class LocaleUtils {
@Retention(RetentionPolicy.SOURCE)
@StringDef({ENGLISH, FRENCH, SPANISH})
public @interface LocaleDef {
String[] SUPPORTED_LOCALES = {ENGLISH, FRENCH, SPANISH};
}
public static final String ENGLISH = "en";
public static final String FRENCH = "fr";
public static final String SPANISH = "es";
public static void initialize(Context context) {
setLocale(context, ENGLISH);
}
public static void initialize(Context context, @LocaleDef String defaultLanguage) {
setLocale(context, defaultLanguage);
}
public static boolean setLocale(Context context, @LocaleDef String language) {
return updateResources(context, language);
}
private static boolean updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
context.createConfigurationContext(configuration);
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return true;
}
}
Ahora, cuando selecciona el idioma de su aplicación, guarde el código de idioma en Preferencias compartidas como se muestra a continuación
private static SharedPreferences getDefaultSharedPreference(Context context) {
if (PreferenceManager.getDefaultSharedPreferences(Application.getInstance().getApplicationContext()) != null)
return PreferenceManager.getDefaultSharedPreferences(Application.getInstance().getApplicationContext());
else
return null;
}
public static void setSelectedLanguageId(String id){
final SharedPreferences prefs = getDefaultSharedPreference(Application.getInstance().getApplicationContext());
SharedPreferences.Editor editor = prefs.edit();
editor.putString("app_language_id", id);
editor.apply();
}
public static String getSelectedLanguageId(){
return getDefaultSharedPreference(Application.getInstance().getApplicationContext())
.getString("app_language_id", "en");
}
Estas tres funciones deben estar escritas dentro de una clase de utilidad (su preferencia). Luego, cuando seleccione el idioma de la aplicación desde la aplicación, llame a la función setSelectedLanguageId () y pase la identificación del idioma como parámetro.
De esta manera ha guardado el idioma seleccionado en su aplicación. Ahora en tu clase de aplicación escribe una función como esta
public void initAppLanguage(Context context){
LocaleUtils.initialize(context, PreferenceUtil.getSelectedLanguageId() );
}
Aquí el PreferenceUtil es mi clase de utilidad. Debe reemplazarlo con su función de clase de utilidad.
También debe crear una variable en su clase de aplicación
private static Application applicationInstance;
y en el método onCreate de su clase de aplicación, inicialice applicationInstance para que sea el contexto de aplicaciones como este
applicationInstance = this;
Ahora escribe una función getter en tu clase de aplicación
public static synchronized Application getInstance() {
return applicationInstance;
}
Y ahora, cuando comience su primera actividad, llame a este método en onCreate de su actividad.
Application.getInstance().initAppLanguage(this);
Recuerde que estamos pasando el contexto de la actividad a la función initAppLanguage (), no al contexto de la aplicación. Pasar el contexto de la aplicación no lo hará funcionar en Oreo (al menos para mí).
Entonces, cuando seleccione el idioma, intente reiniciar su aplicación completamente. Usted puede lograr esto por
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
startActivity (i);
¡Espero que esto te ayude!
Aquí está la solución completa trabajada para kitkat, Lollipop, Marshmallow, Nougat y Oreo también. Simplemente siga todos los pasos a continuación.
Primero crea una clase de java como abajo
import android.content.Context;
import android.content.res.Configuration;
import java.util.Locale;
public class LocaleUtils {
public static void updateConfig(Context mContext, String sLocale) {
Locale locale = new Locale(sLocale);
Locale.setDefault(locale);
Configuration config = mContext.getResources().getConfiguration();
config.locale = locale;
mContext.getResources().updateConfiguration(config,
mContext.getResources().getDisplayMetrics());
}
}
Ahora agregue este fragmento en el botón Haga clic donde desee cambiar la configuración regional
String lang="hi";//pass your language here
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.putString("lang", lang");
editor.putBoolean("langSelected", true);
editor.apply();
LocaleUtils.updateConfig(mContext,lang);
Intent intent = mContext.getIntent();
mContext.overridePendingTransition(0, 0);
mContext.finish();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.overridePendingTransition(0, 0);
mContext.startActivity(intent);
Finalmente, pegue el siguiente código en Splash Activity o en Launching Activity.
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String lang = preferences.getString("lang", "");
boolean langSelected = preferences.getBoolean("langSelected", false);
SharedPreferences.Editor editor = preferences.edit();
if (langSelected) {
editor.clear();
editor.putString("lang", lang);
editor.putBoolean("langSelected", true);
editor.apply();
LocaleUtils.updateConfig(this,lang);
} else {
LocaleUtils.updateConfig(this, Locale.getDefault().getLanguage());
editor.clear();
editor.putString("lang", Locale.getDefault().getLanguage());
editor.putBoolean("langSelected", false);
editor.apply();
}