Imposta le impostazioni internazionali a livello di codice


139

La mia app supporta 3 (presto 4) lingue. Poiché diverse versioni locali sono abbastanza simili, vorrei offrire all'utente la possibilità di modificare le impostazioni locali nella mia applicazione, ad esempio una persona italiana potrebbe preferire lo spagnolo piuttosto che l'inglese.

Esiste un modo per l'utente di selezionare tra le impostazioni locali disponibili per l'applicazione e quindi modificare le impostazioni locali utilizzate? Non vedo come un problema impostare le impostazioni locali per ogni attività poiché è un compito semplice da eseguire in una classe base.


Se hai bisogno di un modo per ripristinare le impostazioni internazionali predefinite in un secondo momento o se hai bisogno di una preferenza di lingua che contiene un elenco di lingue e se desideri modificare le impostazioni internazionali in modo più conveniente, questo può essere utile: github.com/delight-im/Android -Lingue
caw

Risposte:


114

Per le persone che cercano ancora questa risposta, poiché è configuration.localestato deprecato dall'API 24, ora puoi utilizzare:

configuration.setLocale(locale);

Prendi in considerazione che minSkdVersion per questo metodo è API 17.

Codice di esempio 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);
    }
}

Non dimenticare che, se si modifica la locale con un'attività in esecuzione, sarà necessario riavviarla affinché le modifiche abbiano effetto.

MODIFICA 11 MAGGIO 2018

A partire dal post di @ CookieMonster, potresti avere problemi a mantenere la modifica delle impostazioni locali nelle versioni API superiori. In tal caso, aggiungi il seguente codice all'attività di base in modo da aggiornare le impostazioni internazionali del contesto su ogni creazione di attività:

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

Se lo usi, non dimenticare di salvare la lingua in SharedPreferences quando imposti la locale con setLocate(locale)

MODIFICA 7 APRILE 2020

Potresti riscontrare problemi in Android 6 e 7, e ciò accade a causa di un problema nelle librerie androidx durante la gestione della modalità notturna. Per questo dovrai anche sovrascrivere applyOverrideConfigurationl'attività di base e aggiornare le impostazioni locali della configurazione nel caso in cui ne venga creata una nuova.

Codice di esempio:

@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
Funziona per le attività, ma c'è un modo per aggiornare il contesto dell'applicazione?
alekop,

2
Dopo aver cambiato androidx.appcompat:appcompat:la versione da 1.0.2per 1.1.0non funzionante su Android 7, ma lavorando su Android 9.
Bek

4
Lo stesso problema per me e 1.1.0androidx
Alexander Dadukin,

2
Lo stesso problema per me. Dopo che sono passato a androidx.appcompat: appcompat: 1.1.0 'lib
Rahul Jidge

4
Problema con appcompat:1.1.0può essere risolto con appcompat:1.2.0-alpha02e codice 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));interno@TargetApi(Build.VERSION_CODES.N) updateResourcesLocale()
Vojtech Pohl

178

Spero che questo aiuto (in 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
Quindi questo deve essere impostato per ogni attività?
Tobias,

6
1. è obbligatorio utilizzare getBaseContext () o è meglio utilizzare il contesto dell'applicazione? 2. questo codice dovrebbe essere chiamato in ogni attività? Grazie.
Paul,

10
Ho inserito questo codice in onCreate () della mia attività di avvio (e in nessun altro luogo) e sono rimasto piacevolmente sorpreso nel vedere che le impostazioni internazionali si applicavano all'intera app. Questo è in un'app con targeting 4.3 con un minSDK di 14 (ICS).
IAmKale,

8
Non è necessario creare un nuovo oggetto Configuration. È possibile utilizzare la configurazione corrente e aggiornarla: getResources (). GetConfiguration ()
jmart

1
non usare la nuova configurazione (); cambia textAppearance, fontSize
Jemshit Iskenderov

22

Ho avuto un problema con l'impostazione delle impostazioni internazionali a livello di codice con dispositivi con Android OS N e versioni successive . Per me la soluzione è stata scrivere questo codice nella mia attività di base:

(se non hai un'attività di base, dovresti apportare queste modifiche in tutte le tue attività)

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

nota che qui non è sufficiente chiamare

createConfigurationContext(configuration)

è inoltre necessario ottenere il contesto restituito da questo metodo e quindi impostare questo contesto nel attachBaseContextmetodo.


Questa è la soluzione più semplice e funzionante! Questa dovrebbe essere la risposta accettata.
Prasad Pawar,

3
Questo codice funziona molto su Android sopra 7 ma nelle versioni sotto N non funziona. Avete delle soluzioni?
Matin Ashtiani,

Non sono sicuro perché funziona per me. Vuoi inviarmi la tua implementazione in modo che io possa dare un'occhiata?
CookieMonster

2
Non funziona nelle versioni con Android N perché resources.updateConfiguration deve essere chiamato in onCreate () invece di attachBaseContext ()
Chandler,

@Chandler ha ragione. Per Android 6-, chiama il updateBaseContextLocalemetodo onCreatedell'attività genitore / base.
Azizjon Kholmatov,

22

Poiché nessuna risposta è completa per l'attuale modo di risolvere questo problema, provo a dare istruzioni per una soluzione completa. Si prega di commentare se manca qualcosa o potrebbe essere fatto meglio.

Informazione Generale

Innanzitutto, esistono alcune librerie che vogliono risolvere il problema ma sembrano tutte obsolete o mancano alcune funzionalità:

Inoltre, penso che scrivere una libreria potrebbe non essere un modo buono / facile per risolvere questo problema perché non c'è molto da fare, e ciò che deve essere fatto è piuttosto cambiare il codice esistente piuttosto che usare qualcosa di completamente disaccoppiato. Pertanto ho composto le seguenti istruzioni che dovrebbero essere complete.

La mia soluzione si basa principalmente su https://github.com/gunhansancar/ChangeLanguageExample (come già collegato da localhost ). È il miglior codice che ho trovato su cui orientarmi. Alcune osservazioni:

  • Se necessario, fornisce diverse implementazioni per modificare le impostazioni locali per Android N (e versioni successive) e versioni precedenti
  • Utilizza un metodo updateViews()in ogni attività per aggiornare manualmente tutte le stringhe dopo aver modificato getString(id)le impostazioni locali (usando il solito ) che non è necessario nell'approccio mostrato di seguito
  • Supporta solo le lingue e non le localizzazioni complete (che includono anche i codici regione (paese) e variante)

L'ho cambiato un po ', disaccoppiando la parte che persiste la locale prescelta (come si potrebbe desiderare di fare separatamente, come suggerito di seguito).

Soluzione

La soluzione è composta dai seguenti due passaggi:

  • Modifica in modo permanente le impostazioni internazionali da utilizzare dall'app
  • Fai in modo che l'app usi le impostazioni internazionali personalizzate, senza riavviare

Passaggio 1: modifica le impostazioni internazionali

Usa la classe LocaleHelper, basata su LocaleHelper di gunhansancar :

  • Aggiungi a ListPreferencein a PreferenceFragmentcon le lingue disponibili (deve essere mantenuto quando le lingue devono essere aggiunte in seguito)
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 SettingsFragmentsimile come segue:

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

Creare un locales.xmlelenco di risorse con tutte le versioni locali con le traduzioni disponibili nel modo seguente ( elenco di codici locali ):

<!-- 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>

Nella tua PreferenceScreenè possibile utilizzare la seguente sezione per consentire all'utente di selezionare le lingue disponibili:

<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>

che utilizza le seguenti stringhe da 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>

Passaggio 2: fai in modo che l'app usi le impostazioni internazionali personalizzate

Ora imposta ciascuna attività per utilizzare il set di impostazioni internazionali personalizzato. Il modo più semplice per ottenere questo risultato è avere una classe base comune per tutte le attività con il seguente codice (dove si trova il codice importante attachBaseContext(Context base)e 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();
        }
    }
}

Quello che fa è

  • Sostituisci attachBaseContext(Context base)per utilizzare le impostazioni internazionali precedentemente persistentiLocaleHelper
  • Rileva una modifica delle impostazioni locali e ricrea l'attività per aggiornarne le stringhe

Note su questa soluzione

  • La ricreazione di un'attività non aggiorna il titolo di ActionBar (come già osservato qui: https://github.com/gunhansancar/ChangeLanguageExample/issues/1 ).

    • Ciò può essere ottenuto semplicemente inserendo setTitle(R.string.mytitle)il onCreate()metodo di ciascuna attività.
  • Consente all'utente di scegliere le impostazioni internazionali predefinite del sistema, nonché le impostazioni internazionali predefinite dell'app (che può essere denominata, in questo caso "inglese").

  • fr-rCAFinora sono supportati solo codici di lingua, nessuna regione (paese) e codici variante (come ). Per supportare le specifiche locali complete, è possibile utilizzare un parser simile a quello della libreria Android-Languages (che supporta la regione ma non i codici variante).

    • Se qualcuno trova o ha scritto un buon parser, aggiungi un commento in modo da poterlo includere nella soluzione.

1
Eccellente ma re dell'incubo
Odys

1
Inferno no, la mia app è già troppo complessa, questo approccio sarebbe un incubo da mantenere in futuro.
Josh,

@Josh Puoi spiegarlo un po 'di più? In realtà, solo alcune righe devono essere aggiunte a ciascuna classe base di attività che usi. Vedo che potrebbe non essere possibile utilizzare la stessa classe base per tutte le attività, ma anche i progetti più grandi dovrebbero essere in grado di andare d'accordo con alcuni. La programmazione orientata all'aspetto potrebbe essere d'aiuto, ma la composizione (sposta il codice da attachBaseContext(Context base)e onResume()verso una classe separata) può fare il trucco. Quindi tutto ciò che devi fare è dichiarare un oggetto in ciascuna classe base di attività e delegare quelle due chiamate.
user905686

Se l'utente modifica le impostazioni internazionali, è possibile modificare anche le impostazioni internazionali di tutte le pagine di attività precedenti?
Raju yourPepe,

Questa è la migliore risposta a questo problema. Grazie fratello, funziona
Alok Gupta il

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

Usa questo metodo di supporto per forzare impostazioni internazionali specifiche.

UDPATE 22 AGOSTO 2017. Meglio usare questo approccio .


4

Aggiungi una classe di supporto con il seguente metodo:

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

    }
}

E chiamalo nella tua attività di avvio, come MainActivity.java:

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

3

semplice e facile

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

dove "en" è il codice della lingua e "US" è il codice del paese.


Come indicato nel mio post conf.locale=locale;è deprecato, e lo è anche updateConfiguration.
Ricardo,

molto semplice e meno complicato :)
Ramkesh Yadav

2

Valido per API16 su API28 Posiziona questo metodo solo dove:

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

Inserisci questo codice in tutte le tue attività usando:

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

oppure chiama localeUpdateResources su frammenti, adattatori, ecc. dove è necessario il nuovo contesto.

Crediti: Yaroslav Berezanskyi


2

C'è un modo super semplice.

in BaseActivity, Activity o Fragment sovrascrive attachBaseContext

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

estensione

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

Ho trovato il androidx.appcompat:appcompat:1.1.0bug può anche essere fissato semplicemente chiamando getResources()inapplyOverrideConfiguration()

@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

Per chi ha provato di tutto ma non ha funzionato . Si prega di verificare che se impostato darkmodecon AppCompatDelegate.setDefaultNightModee il sistema non è scuro, quindi Configuration.setLocalenon funzionerà sopra Andorid 7.0 .

Aggiungi questo codice in ogni tua attività per risolvere questo 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

Inserisci questo codice nella tua attività

 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();
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.