Establecer configuración regional mediante programación


139

Mi aplicación admite 3 (pronto 4) idiomas. Dado que varias configuraciones regionales son bastante similares, me gustaría darle al usuario la opción de cambiar la configuración regional en mi aplicación, por ejemplo, una persona italiana podría preferir el español al inglés.

¿Hay alguna manera para que el usuario seleccione entre las configuraciones regionales que están disponibles para la aplicación y luego cambie la configuración regional que se usa? No lo veo como un problema para establecer la configuración regional para cada actividad, ya que es una tarea sencilla de realizar en una clase base.


Si necesita una forma de restaurar la configuración regional predeterminada más adelante o si necesita una preferencia de idioma que contenga una lista de idiomas, y si desea cambiar la configuración regional más convenientemente, esto puede ser útil: github.com/delight-im/Android -Lenguas
CAW

Respuestas:


114

Para las personas que todavía buscan esta respuesta, dado que configuration.localefue desaprobada de API 24, ahora puede usar:

configuration.setLocale(locale);

Tenga en cuenta que minSkdVersion para este método es API 17.

Código de ejemplo completo:

@SuppressWarnings("deprecation")
private void setLocale(Locale locale){
    SharedPrefUtils.saveLocale(locale); // optional - Helper method to save the selected language to SharedPreferences in case you might need to attach to activity context (you will need to code this)
    Resources resources = getResources();
    Configuration configuration = resources.getConfiguration();
    DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
        configuration.setLocale(locale);
    } else{
        configuration.locale=locale;
    }
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
        getApplicationContext().createConfigurationContext(configuration);
    } else {
        resources.updateConfiguration(configuration,displayMetrics);
    }
}

No olvide que, si cambia la configuración regional con una actividad en ejecución, deberá reiniciarla para que los cambios surtan efecto.

EDITAR 11 de mayo de 2018

A partir de la publicación de @ CookieMonster, es posible que tenga problemas para mantener el cambio de configuración regional en versiones de API más altas. Si es así, agregue el siguiente código a su Actividad base para actualizar la configuración regional de contexto en cada creación de Actividad:

@Override
protected void attachBaseContext(Context base) {
     super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPrefUtils.getSavedLanguage(); // Helper method to get saved language from SharedPreferences
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N_MR1)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = new Configuration(context.getResources().getConfiguration())
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

Si usa esto, no olvide guardar el idioma en SharedPreferences cuando configure la configuración regional con setLocate(locale)

EDITAR 7 DE ABRIL 2020

Es posible que experimente problemas en Android 6 y 7, y esto sucede debido a un problema en las bibliotecas de Androidx al manejar el modo nocturno. Para esto, también deberá anular applyOverrideConfigurationsu actividad base y actualizar la configuración regional en caso de que se cree una nueva configuración regional nueva.

Código de muestra:

@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        // update overrideConfiguration with your locale  
        setLocale(overrideConfiguration) // you will need to implement this
    }
    super.applyOverrideConfiguration(overrideConfiguration);
} 

2
Esto funciona para actividades, pero ¿hay alguna manera de actualizar el contexto de la aplicación?
alekop

2
Después de cambiar la androidx.appcompat:appcompat:versión de 1.0.2a 1.1.0no funciona en Android 7, pero funciona en Android 9.
Bek

44
El mismo problema para mí y 1.1.0androidx
Alexander Dadukin, el

2
El mismo problema para mi. Después de cambiar a androidx.appcompat: appcompat: 1.1.0 'lib
Rahul Jidge

44
El problema appcompat:1.1.0se puede solucionar con appcompat:1.2.0-alpha02y codificar en el Set<Locale> set = new LinkedHashSet<>(); // bring the target locale to the front of the list set.add(locale); LocaleList all = LocaleList.getDefault(); for (int i = 0; i < all.size(); i++) { // append other locales supported by the user set.add(all.get(i)); } Locale[] locales = set.toArray(new Locale[0]); configuration.setLocales(new LocaleList(locales));interior@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl

178

Espero que esta ayuda (en onResume):

Locale locale = new Locale("ru");
Locale.setDefault(locale);
Configuration config = getBaseContext().getResources().getConfiguration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
      getBaseContext().getResources().getDisplayMetrics());

2
Entonces, ¿esto tiene que establecerse para cada actividad?
Tobias

66
1. es obligatorio usar getBaseContext () o debería ser mejor usar el contexto de la aplicación? 2. Este código debe ser llamado en cada actividad? Gracias.
Paul

10
Coloqué este código en onCreate () de mi actividad de iniciador (y en ningún otro lugar) y me sorprendió gratamente ver que la configuración regional se aplicaba a toda la aplicación. Esto está en una aplicación dirigida a 4.3 con un minSDK de 14 (ICS).
IAmKale

8
No es necesario crear un nuevo objeto de configuración. Puede usar la configuración actual y actualizarla: getResources (). GetConfiguration ()
jmart

1
no use la nueva Configuración () ;, cambia el texto Apariencia, fontSize
Jemshit Iskenderov

22

Tuve un problema con la configuración regional mediante programación con dispositivos que tienen Android OS N y superior . Para mí, la solución fue escribir este código en mi actividad base:

(si no tiene una actividad base, entonces debe hacer estos cambios en todas sus actividades)

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(updateBaseContextLocale(base));
}

private Context updateBaseContextLocale(Context context) {
    String language = SharedPref.getInstance().getSavedLanguage();
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return updateResourcesLocale(context, locale);
    }

    return updateResourcesLocaleLegacy(context, locale);
}

@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
    Resources resources = context.getResources();
    Configuration configuration = resources.getConfiguration();
    configuration.locale = locale;
    resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    return context;
}

tenga en cuenta que aquí no es suficiente llamar

createConfigurationContext(configuration)

también necesita obtener el contexto que devuelve este método y luego establecer este contexto en el attachBaseContextmétodo.


¡Esta es la solución más fácil y funcional! Esta debería ser la respuesta aceptada.
Prasad Pawar

3
Este código funciona mucho en Android por encima de 7 pero en versiones por debajo de N no funciona. ¿Tienes alguna solución?
Matin Ashtiani

No estoy seguro porque me está funcionando. ¿Quieres enviarme tu implementación para que pueda echar un vistazo?
CookieMonster

2
No funciona en versiones con Android N porque resources.updateConfiguration debe llamarse en onCreate () en lugar de attachBaseContext ()
Chandler

@Chandler tiene razón. Para Android 6-, llame el updateBaseContextLocalemétodo onCreatede su actividad principal / base.
Azizjon Kholmatov

22

Como no hay una respuesta completa para la forma actual de resolver este problema, trato de dar instrucciones para una solución completa. Comente si falta algo o podría hacerse mejor.

Información general

Primero, existen algunas bibliotecas que quieren resolver el problema pero todas parecen anticuadas o les faltan algunas características:

Además, creo que escribir una biblioteca podría no ser una forma buena / fácil de resolver este problema porque no hay mucho que hacer, y lo que hay que hacer es cambiar el código existente en lugar de usar algo completamente desacoplado. Por lo tanto, compuse las siguientes instrucciones que deberían estar completas.

Mi solución se basa principalmente en https://github.com/gunhansancar/ChangeLanguageExample (como ya está vinculado por localhost ). Es el mejor código que encontré para orientar. Algunas observaciones:

  • Según sea necesario, proporciona diferentes implementaciones para cambiar la configuración regional para Android N (y superior) y posterior
  • Utiliza un método updateViews()en cada Actividad para actualizar manualmente todas las cadenas después de cambiar la configuración regional (usando el habitual getString(id)) que no es necesario en el enfoque que se muestra a continuación
  • Solo admite idiomas y configuraciones regionales no completas (que también incluyen códigos de región (país) y variantes)

Lo cambié un poco, desacoplando la parte que persiste en la configuración regional elegida (ya que uno podría querer hacerlo por separado, como se sugiere a continuación).

Solución

La solución consta de los siguientes dos pasos:

  • Cambiar permanentemente la configuración regional que utilizará la aplicación
  • Haga que la aplicación use el conjunto de configuraciones regionales personalizadas, sin reiniciar

Paso 1: cambiar la configuración regional

Use la clase LocaleHelper, basada en LocaleHelper de gunhansancar :

  • Agregue un ListPreferenceen a PreferenceFragmentcon los idiomas disponibles (debe mantenerse cuando los idiomas deben agregarse más adelante)
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;

import java.util.Locale;

import mypackage.SettingsFragment;

/**
 * Manages setting of the app's locale.
 */
public class LocaleHelper {

    public static Context onAttach(Context context) {
        String locale = getPersistedLocale(context);
        return setLocale(context, locale);
    }

    public static String getPersistedLocale(Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SettingsFragment.KEY_PREF_LANGUAGE, "");
    }

    /**
     * Set the app's locale to the one specified by the given String.
     *
     * @param context
     * @param localeSpec a locale specification as used for Android resources (NOTE: does not
     *                   support country and variant codes so far); the special string "system" sets
     *                   the locale to the locale specified in system settings
     * @return
     */
    public static Context setLocale(Context context, String localeSpec) {
        Locale locale;
        if (localeSpec.equals("system")) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                locale = Resources.getSystem().getConfiguration().getLocales().get(0);
            } else {
                //noinspection deprecation
                locale = Resources.getSystem().getConfiguration().locale;
            }
        } else {
            locale = new Locale(localeSpec);
        }
        Locale.setDefault(locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, locale);
        } else {
            return updateResourcesLegacy(context, locale);
        }
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, Locale locale) {
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, Locale locale) {
        Resources resources = context.getResources();

        Configuration configuration = resources.getConfiguration();
        configuration.locale = locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            configuration.setLayoutDirection(locale);
        }

        resources.updateConfiguration(configuration, resources.getDisplayMetrics());

        return context;
    }
}

Crea un me SettingsFragmentgusta de la siguiente manera:

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * Fragment containing the app's main settings.
 */
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_LANGUAGE = "pref_key_language";

    public SettingsFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_settings, container, false);
        return view;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        switch (key) {
            case KEY_PREF_LANGUAGE:
                LocaleHelper.setLocale(getContext(), PreferenceManager.getDefaultSharedPreferences(getContext()).getString(key, ""));
                getActivity().recreate(); // necessary here because this Activity is currently running and thus a recreate() in onResume() would be too late
                break;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        // documentation requires that a reference to the listener is kept as long as it may be called, which is the case as it can only be called from this Fragment
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
}

Cree un recurso que locales.xmlenumere todas las configuraciones regionales con las traducciones disponibles de la siguiente manera ( lista de códigos locales ):

<!-- Lists available locales used for setting the locale manually.
     For now only language codes (locale codes without country and variant) are supported.
     Has to be in sync with "settings_language_values" in strings.xml (the entries must correspond).
  -->
<resources>
    <string name="system_locale" translatable="false">system</string>
    <string name="default_locale" translatable="false"></string>
    <string-array name="locales">
        <item>@string/system_locale</item> <!-- system setting -->
        <item>@string/default_locale</item> <!-- default locale -->
        <item>de</item>
    </string-array>
</resources>

En su PreferenceScreenpuede usar la siguiente sección para permitir al usuario seleccionar los idiomas disponibles:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="@string/preferences_category_general">
        <ListPreference
            android:key="pref_key_language"
            android:title="@string/preferences_language"
            android:dialogTitle="@string/preferences_language"
            android:entries="@array/settings_language_values"
            android:entryValues="@array/locales"
            android:defaultValue="@string/system_locale"
            android:summary="%s">
        </ListPreference>
    </PreferenceCategory>
</PreferenceScreen>

que utiliza las siguientes cadenas de strings.xml:

<string name="preferences_category_general">General</string>
<string name="preferences_language">Language</string>
<!-- NOTE: Has to correspond to array "locales" in locales.xml (elements in same orderwith) -->
<string-array name="settings_language_values">
    <item>Default (System setting)</item>
    <item>English</item>
    <item>German</item>
</string-array>

Paso 2: haga que la aplicación use la configuración regional personalizada

Ahora configure cada actividad para usar el conjunto de configuraciones regionales personalizadas. La forma más fácil de lograr esto es tener una clase base común para todas las actividades con el siguiente código (donde está el código importante attachBaseContext(Context base)y onResume()):

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import mypackage.LocaleHelper;
import mypackage.R;

/**
 * {@link AppCompatActivity} with main menu in the action bar. Automatically recreates
 * the activity when the locale has changed.
 */
public class MenuAppCompatActivity extends AppCompatActivity {
    private String initialLocale;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initialLocale = LocaleHelper.getPersistedLocale(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_settings:
                Intent intent = new Intent(this, SettingsActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (initialLocale != null && !initialLocale.equals(LocaleHelper.getPersistedLocale(this))) {
            recreate();
        }
    }
}

Lo que hace es

  • Anular attachBaseContext(Context base)para usar la configuración regional que anteriormente persistía conLocaleHelper
  • Detecte un cambio de la configuración regional y vuelva a crear la Actividad para actualizar sus cadenas.

Notas sobre esta solución

  • Volver a crear una actividad no actualiza el título de ActionBar (como ya se observó aquí: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).

    • Esto se puede lograr simplemente teniendo un setTitle(R.string.mytitle)en el onCreate()método de cada actividad.
  • Permite al usuario elegir la configuración regional predeterminada del sistema, así como la configuración regional predeterminada de la aplicación (que puede denominarse, en este caso, "inglés").

  • fr-rCAHasta ahora, solo se admiten códigos de idioma, ninguna región (país) y códigos de variantes (como ). Para admitir las especificaciones locales completas, se puede utilizar un analizador similar al de la biblioteca de idiomas de Android (que admite regiones pero no códigos de variantes).

    • Si alguien encuentra o ha escrito un buen analizador, agregue un comentario para que pueda incluirlo en la solución.

1
Excelente pero rey de la pesadilla
Odys

1
Demonios, no, mi aplicación ya es demasiado compleja, este enfoque sería una pesadilla para mantener en el futuro.
Josh

@ Josh ¿Puedes explicar esto un poco más? En realidad, solo se deben agregar unas pocas líneas a cada clase base de Actividad que use. Veo que podría no ser posible usar la misma clase base para todas las actividades, pero incluso los proyectos más grandes deberían poder llevarse bien con algunas. La programación orientada a aspectos podría ayudar aquí, pero la composición (mover el código desde attachBaseContext(Context base)y onResume()hacia una clase separada) puede ser la solución. Entonces todo lo que tiene que hacer es declarar un objeto en cada clase base de actividad y delegar esas dos llamadas.
user905686

Si el usuario cambia su configuración regional, ¿también se puede cambiar la configuración regional de todas las páginas de actividades anteriores?
Raju yourPepe

Esta es la mejor respuesta sobre este tema. Gracias hermano, funciona
Alok Gupta

16
@SuppressWarnings("deprecation")
public static void forceLocale(Context context, String localeCode) {
    String localeCodeLowerCase = localeCode.toLowerCase();

    Resources resources = context.getApplicationContext().getResources();
    Configuration overrideConfiguration = resources.getConfiguration();
    Locale overrideLocale = new Locale(localeCodeLowerCase);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        overrideConfiguration.setLocale(overrideLocale);
    } else {
        overrideConfiguration.locale = overrideLocale;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.getApplicationContext().createConfigurationContext(overrideConfiguration);
    } else {
        resources.updateConfiguration(overrideConfiguration, null);
    }
}

Simplemente use este método auxiliar para forzar la configuración regional específica.

UDPATE 22 AGOSTO 2017. Mejor use este enfoque .


4

Agregue una clase auxiliar con el siguiente método:

public class LanguageHelper {
    public static final void setAppLocale(String language, Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Resources resources = activity.getResources();
            Configuration configuration = resources.getConfiguration();
            configuration.setLocale(new Locale(language));
            activity.getApplicationContext().createConfigurationContext(configuration);
        } else {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            Configuration config = activity.getResources().getConfiguration();
            config.locale = locale;
            activity.getResources().updateConfiguration(config,
                    activity.getResources().getDisplayMetrics());
        }

    }
}

Y llámalo en tu actividad de inicio, como MainActivity.java:

public void onCreate(Bundle savedInstanceState) {
    ...
    LanguageHelper.setAppLocale("fa", this);
    ...
}

3

simple y fácil

Locale locale = new Locale("en", "US");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = locale;
res.updateConfiguration(conf, dm);

donde "en" es el código del idioma y "EE. UU." es el código del país.


Como se indica en mi publicación conf.locale=locale;está en desuso, y también lo es updateConfiguration.
Ricardo

muy simple y menos complicado :)
Ramkesh Yadav

2

Válido para API16 a API28 Simplemente coloque este método en algún lugar:

    Context newContext = context;

        Locale locale = new Locale(languageCode);
        Locale.setDefault(locale);

        Resources resources = context.getResources();
        Configuration config = new Configuration(resources.getConfiguration());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {

        config.setLocale(locale);
                newContext = context.createConfigurationContext(config);

        } else {

        config.locale = locale;
                resources.updateConfiguration(config, resources.getDisplayMetrics());
        }

    return newContext;
}

Inserte este código en todas sus actividades usando:

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(localeUpdateResources(base, "<-- language code -->"));
    }

o llame a localeUpdateResources sobre fragmentos, adaptadores, etc., donde necesite el nuevo contexto.

Créditos: Yaroslav Berezanskyi


2

Hay una forma super simple.

en BaseActivity, Activity o Fragment override attachBaseContext

 override fun attachBaseContext(context: Context) {
    super.attachBaseContext(context.changeLocale("tr"))
}

extensión

fun Context.changeLocale(language:String): Context {
    val locale = Locale(language)
    Locale.setDefault(locale)
    val config = this.resources.configuration
    config.setLocale(locale)
    return createConfigurationContext(config)
}

2

He encontrado el androidx.appcompat:appcompat:1.1.0fallo también puede ser fijado simplemente llamando getResources()enapplyOverrideConfiguration()

@Override public void
applyOverrideConfiguration(Configuration cfgOverride)
{
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
      Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    // add this to fix androidx.appcompat:appcompat 1.1.0 bug
    // which happens on Android 6.x ~ 7.x
    getResources();
  }

  super.applyOverrideConfiguration(cfgOverride);
}

1
 /**
 * Requests the system to update the list of system locales.
 * Note that the system looks halted for a while during the Locale migration,
 * so the caller need to take care of it.
 */
public static void updateLocales(LocaleList locales) {
    try {
        final IActivityManager am = ActivityManager.getService();
        final Configuration config = am.getConfiguration();

        config.setLocales(locales);
        config.userSetLocale = true;

        am.updatePersistentConfiguration(config);
    } catch (RemoteException e) {
        // Intentionally left blank
    }
}

1

Para quienes intentaron todo pero no funcionaron . Compruebe que si configuró darkmodecon AppCompatDelegate.setDefaultNightModey el sistema no está oscuro, Configuration.setLocaleno funcionará por encima de Andorid 7.0 .

Agregue este código en todas sus actividades para resolver este problema:

override fun applyOverrideConfiguration(overrideConfiguration: Configuration?) {
  if (overrideConfiguration != null) {
    val uiMode = overrideConfiguration.uiMode
    overrideConfiguration.setTo(baseContext.resources.configuration)
    overrideConfiguration.uiMode = uiMode
  }
  super.applyOverrideConfiguration(overrideConfiguration)
}

-1

Pon este código en tu actividad

 if (id==R.id.uz)
    {
        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
        return true;
    }
    if (id == R.id.ru) {

        LocaleHelper.setLocale(MainActivity.this, mLanguageCode);

        //It is required to recreate the activity to reflect the change in UI.
        recreate();
    }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.