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