webentwicklung-frage-antwort-db.com.de

So ändern Sie die App-Sprache für Android O/Oreo/api 26

Ich möchte die Sprache der App ändern und das funktioniert gut, bis API 26.

Für api> 25 stelle ich Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale); vor setContentView(R.layout.activity_main);, aber nichts ändert sich.

Die docs erklären nicht viel darüber.

Ja, bei der Android-Oreo-Lokalisierung funktioniert die Updatekonfiguration nicht einwandfrei. In Android N selbst ist es jedoch veraltet. Anstelle von updateconfiguration verwenden Sie createconfiguration in jedem Anhangskontext. es funktioniert gut für mich. Versuche dies...

In Ihrer Aktivität fügen Sie dies hinzu .. 

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

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

Ich hatte das gleiche Problem: seit Android 8.0+ haben einige Teile meiner App ihre Sprache nicht mehr geändert. Das Aktualisieren von Anwendungs- und Aktivitätskontext hilft mir dabei. Hier ist ein Beispiel für die MainActivity-Funktion:

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

updateConfiguration ist veraltet und Sie sollten createConfigurationContext verwenden. Ich habe es so gelöst:

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

Für alle Android-Versionen bis Oreo aktualisiert

Erstellen Sie eine Klasse wie diese

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

}

Wenn Sie jetzt die Sprache aus Ihrer App auswählen, speichern Sie den Sprachcode in den gemeinsamen Einstellungen wie unten

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

Diese drei Funktionen sollten in eine Dienstklasse geschrieben werden (Ihre Präferenz). Wenn Sie dann die App-Sprache in der App auswählen, rufen Sie die Funktion setSelectedLanguageId () auf und übergeben Sie die Sprach-ID als Parameter.

Auf diese Weise haben Sie die ausgewählte Sprache in Ihrer App gespeichert. Schreiben Sie jetzt in Ihrer Anwendungsklasse eine Funktion wie diese 

public void initAppLanguage(Context context){
    LocaleUtils.initialize(context, PreferenceUtil.getSelectedLanguageId() );
}

Hier ist das PreferenceUtil meine Nutzungsklasse. Sie sollten es durch Ihre Utility-Klassenfunktion ersetzen. 

Sie sollten auch eine Variable in Ihrer Anwendungsklasse erstellen

private static Application applicationInstance;

initialisieren Sie in der onCreate-Methode Ihrer Application-Klasse applicationInstance als Anwendungskontext wie folgt

applicationInstance = this; 

Schreiben Sie jetzt eine Getter-Funktion in Ihre Anwendungsklasse

public static synchronized Application getInstance() {
    return applicationInstance;
}

Wenn Sie nun Ihre erste Aktivität starten, rufen Sie diese Methode in onCreate der Aktivität auf 

Application.getInstance().initAppLanguage(this);

Denken Sie daran, dass wir den Kontext der Aktivität an die Funktion initAppLanguage () übergeben, nicht an den Anwendungskontext. Wenn Sie den Anwendungskontext übergeben, wird es in Oreo (zumindest für mich) nicht funktionieren. 

Wenn Sie die Sprache auswählen, versuchen Sie, Ihre Anwendung vollständig neu zu starten. Sie können dies durch erreichen 

Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());

startActivity (i);

Hoffe das hilft dir!

3
emilpmp

Es ist möglich, aber ich würde nicht empfehlen, die Sprache programmatisch einzustellen

Android ist so konzipiert, dass die System-Benutzeroberfläche und Ihre App dieselbe Sprache haben. Wenn Sie sie programmgesteuert ändern, bekämpfen Sie das System

Stattdessen können Sie die Unterstützung für mehrere Sprachen aktivieren, indem Sie verschiedene Sprachen von strings.xml hinzufügen. Dadurch wird die Sprache automatisch geändert

Ich empfehle, diesen Google Developers Artikel durchzulesen:

Unterstützung verschiedener Sprachen und Kulturen

Wenn Sie es wirklich programmgesteuert ändern müssen, können Sie Folgendes tun

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

Bei SDK> = 21 müssen Sie 'Resources.updateConfiguration ()' aufrufen, anderenfalls werden Ressourcen nicht aktualisiert.

Ich hoffe es hilft.

1
Andre Breton

Hier ist die komplette Lösung auch für KitKat, Lollipop, Marshmallow, Nougat und Oreo gearbeitet. Folgen Sie einfach allen unten stehenden Schritten.

Erstellen Sie zuerst eine Java-Klasse wie unten

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

Fügen Sie dieses Snippet nun auf Button hinzu, wo Sie das Gebietsschema ändern möchten

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

Fügen Sie schließlich den folgenden Code in Splash Activity oder in Launching Activity ein.

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

Sie müssen getApplicationContext() anstelle von getContext() verwenden.

Nachdem alle Lösungen in allen Quellen verwendet wurden, fand ich schließlich mein Problem. Das macht mich zwei Tage lang wütend.

Jeder weiß, dass wir in Android Oreo (API 26) createConfigurationContext verwenden müssen. Aber mein Problem ist die Verwendung von Country name mit local. 

Ersetzen 

de_DE mit de

ar_AE mit ar

fa_IR mit fa

Und mein Problem gelöst.

Hoffe, jemandem zu helfen

0
Radesh