Ändern Sie die App-Sprache programmgesteuert in Android


448

Ist es möglich, die Sprache einer App programmgesteuert zu ändern, während weiterhin Android-Ressourcen verwendet werden?

Wenn nicht, ist es möglich, eine Ressource in einer bestimmten Sprache anzufordern?

Ich möchte den Benutzer die Sprache der App aus der App ändern lassen.


4
Sie können die folgende Bibliothek verwenden, die die Sprachliste und die Einstellungen für Ihren Einstellungsbildschirm enthält und die Sprache in Ihrer Anwendung überschreibt: github.com/delight-im/Android-Languages
caw

@ MarcoW. Wissen Sie, ob Android-Languages ​​mit Android 5.0 Lollipop funktioniert?
Neu242

1
@ neu242 Ja, es läuft auf Android 5.0 ohne Probleme.
Caw

1
Sie können die folgende Bibliothek verwenden: github.com/zeugma-solutions/locale-helper-android
josue.0

1
@ Josue.0, dass Bibliothek wirklich die sauberste Lösung dafür ist
Amitavk

Antworten:


376

Es ist möglich. Sie können das Gebietsschema festlegen. Das würde ich jedoch nicht empfehlen. Wir haben es in einem frühen Stadium versucht, es bekämpft im Grunde das System.

Wir haben die gleichen Anforderungen für die Änderung der Sprache, haben uns jedoch entschlossen, die Tatsache zu berücksichtigen, dass die Benutzeroberfläche mit der Benutzeroberfläche des Telefons identisch sein sollte. Es funktionierte über das Einstellen des Gebietsschemas, war aber zu fehlerhaft. Und Sie müssen es jedes Mal einstellen, wenn Sie eine Aktivität (jede Aktivität) aus meiner Erfahrung eingeben. Hier ist ein Code, wenn Sie diesen noch benötigen (ich empfehle das auch nicht)

Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);

Wenn Sie sprachspezifischen Inhalt haben, können Sie diese Basis anhand der Einstellung ändern.


Update am 26. März 2020

public static void setLocale(Activitycontext) {
        Locale locale;
        Sessions session = new Sessions(context);
        //Log.e("Lan",session.getLanguage());
            locale = new Locale(langCode);
        Configuration config = new Configuration(context.getResources().getConfiguration());
        Locale.setDefault(locale);
        config.setLocale(locale);

       context.getBaseContext().getResources().updateConfiguration(config,
              context.getBaseContext().getResources().getDisplayMetrics());
    }

328
Ich kann nicht glauben, dass Android das so schwer macht. Ich verstehe nicht wirklich, warum es eine STRENGE Zuordnung zwischen dem Gebietsschema des Telefons und dem der Anwendung geben sollte. Ich habe mein Telefon immer in englischer Sprache, obwohl ich kein englischer Muttersprachler bin. Der Grund ist, dass die übersetzten halbtechnischen Wörter in meiner eigenen Sprache einfach zu seltsam werden, so dass Englisch so viel einfacher ist. Es erleichtert mir auch, den Ratschlägen aus dem Internet zu folgen. Dies bedeutet jedoch nicht, dass JEDE App auf meinem Telefon Englisch verwenden soll (obwohl dies vollkommen in Ordnung ist). Ich möchte wählen können !!!
Peterh

9
Es sieht so aus, als wäre API Level 17 eingeführt worden Context.createConfigurationContext(), mit dem der Standardkontext mit der länderspezifischen Konfiguration umbrochen und dann aufgerufen werden kann getResources, ohne dass die Konfiguration für die Ressourcenobjekte selbst aktualisiert werden muss.
JAB

8
Sie müssen dies in onCreate () jeder Aktivität einfügen. Andernfalls wird es möglicherweise vom System überschrieben, z. B. wenn Sie Ihr Gerät in den Querformatmodus versetzen und Ihre Aktivität mit einer neuen (vom System bereitgestellten) Konfiguration neu erstellt wird.
Zsolt Safrany

13
Wenn Sie ein RTL-Gebietsschema wie "ar" festlegen und möchten, dass Ihre -ldrtl-Ressourcenordner ebenfalls funktionieren, rufen Sie auch conf.setLayoutDirection (Gebietsschema) auf.
Zsolt Safrany

3
@ZsoltSafrany - Anstatt ein Gespräch hinzugefügt zu conf.setLayoutDirection(locale), können Sie ersetzen conf.locale = new Locale(...))mit conf.setLocale(new Locale(...)). Es wird intern angerufen setLayoutDirection.
Ted Hopp

179

Dieser Code funktioniert wirklich:

fa = Persisch, en = Englisch

Geben Sie Ihren Sprachcode in die languageToLoadVariable ein:

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class Main extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String languageToLoad  = "fa"; // your language
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, 
      getBaseContext().getResources().getDisplayMetrics());
    this.setContentView(R.layout.main);
  }
}

2
Ich möchte das Gebietsschema zur Laufzeit ändern. In Ihrem Code setzen Sie Ihren Code vor die Methode setContentView (). Ihr Code ist also nicht nützlich für mich. So ändern Sie die Sprache zur Laufzeit. In meiner Anwendung gibt es zwei Optionsfelder für Englisch und ein anderes für Arabisch.
Dwivedi Ji

2
@ Buffalo, es ist nur das zweite Argument für die Resources.updateConfigurationMethode. Ich habe den Code eingerückt, um ihn klarer zu machen.
Czechnology

5
Dies funktioniert gut für alle Aktivitäten beim Einstellen der Startaktivität. Der Titel der Aktionsleiste scheint jedoch nicht betroffen zu sein und zeigt weiterhin die Standardsprache an. Irgendeine Idee, was ich vermisst haben könnte?
AndroidMechanic - Viral Patel

8
Config.locale ist veraltet
Zoe

2
anstelle von "config.locale = locale;" benutze "if (Build.VERSION.SDK_INT> = 17) {config.setLocale (Gebietsschema);} else {config.locale = Gebietsschema;}
roghayeh hosseini

36

Ich suchte nach einer Möglichkeit, die Systemsprache programmgesteuert zu ändern. Ich verstehe zwar voll und ganz, dass eine normale Anwendung dies niemals tun sollte und stattdessen auch:

  • Der Benutzer sollte (absichtlich) auf die Systemeinstellungen hingewiesen werden, um sie manuell zu ändern
  • Die Anwendung sollte ihre Lokalisierung wie in der Antwort von Alex beschrieben selbst durchführen

Es bestand die Notwendigkeit, die Sprache des Systems wirklich programmgesteuert zu ändern.

Dies ist eine nicht dokumentierte API und sollte daher nicht für Markt- / Endbenutzeranwendungen verwendet werden!

Wie auch immer, hier ist die Lösung, die ich gefunden habe:

  Locale locale = new Locale(targetLocaleAsString);

  Class amnClass = Class.forName("android.app.ActivityManagerNative");
  Object amn = null;
  Configuration config = null;

  // amn = ActivityManagerNative.getDefault();
  Method methodGetDefault = amnClass.getMethod("getDefault");
  methodGetDefault.setAccessible(true);
  amn = methodGetDefault.invoke(amnClass);

  // config = amn.getConfiguration();
  Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
  methodGetConfiguration.setAccessible(true);
  config = (Configuration) methodGetConfiguration.invoke(amn);

  // config.userSetLocale = true;
  Class configClass = config.getClass();
  Field f = configClass.getField("userSetLocale");
  f.setBoolean(config, true);

  // set the locale to the new value
  config.locale = locale;

  // amn.updateConfiguration(config);
  Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
  methodUpdateConfiguration.setAccessible(true);
  methodUpdateConfiguration.invoke(amn, config);

2
Ausnahme geben invocationtarget Ausnahme
Ravi

1
Nun hängt davon ab, wo die invocationTargetException ausgelöst wird. Dann sollten Sie die Klasse kennen, die geändert wurde.
icyerasor

1
@ Rat-a-tat-a-tat Ratatouille, ab Android 4.2 android.permission.CHANGE_CONFIGURATIONkann das nur von einer App gewährt werden, die mit dem Perform-Schlüssel signiert ist.
Yeung

3
Ich habe meine App in / system / priv-app abgelegt, um das Problem mit Android 6.0 zu umgehen. Details hier .
Weiyin

1
@ Ravi Ich musste meine App von / system / app nach / system / priv-app verschieben, damit es funktioniert
alexislg

31

Wenn Sie die Sprache beibehalten möchten, die in Ihrer gesamten App geändert wurde, müssen Sie zwei Dinge tun.

Erstellen Sie zunächst eine Basisaktivität und erweitern Sie alle Ihre Aktivitäten von dieser:

public class BaseActivity extends AppCompatActivity {

    private Locale mCurrentLocale;

    @Override
    protected void onStart() {
        super.onStart();

        mCurrentLocale = getResources().getConfiguration().locale;
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Locale locale = getLocale(this);

        if (!locale.equals(mCurrentLocale)) {

            mCurrentLocale = locale;
            recreate();
        }
    }

    public static Locale getLocale(Context context){
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

        String lang = sharedPreferences.getString("language", "en");
        switch (lang) {
            case "English":
                lang = "en";
                break;
            case "Spanish":
                lang = "es";
                break;
        }
        return new Locale(lang);
    }
}

Beachten Sie, dass ich die neue Sprache in einer sharedPreference speichere.

Zweitens erstellen Sie eine Erweiterung der Anwendung wie folgt:

    public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        setLocale();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLocale();
    }

    private void setLocale() {

        final Resources resources = getResources();
        final Configuration configuration = resources.getConfiguration();
        final Locale locale = getLocale(this);
        if (!configuration.locale.equals(locale)) {
            configuration.setLocale(locale);
            resources.updateConfiguration(configuration, null);
        }
    }
}

Beachten Sie, dass getLocale () dasselbe ist wie oben.

Das ist alles! Ich hoffe das kann jemandem helfen.


App-Aktivität ist es eine primäre Aktivität, wie eine MainActivity? Zum Beispiel kann ich dies in setLocale () in meiner Methode onCreate () beheben?
Morozov

App ist eine Erweiterung der Anwendung, es ist keine Aktivität. Ich verstehe nicht, was Sie brauchen, sorry. Vielleicht können Sie versuchen, mich noch einmal zu erklären :)
Daniel S.

1
Für diese Android-Noobs wie mich kommen Sie hierher, um zu erfahren, was das Applicationist und wie man es benutzt. mobomo.com/2011/05/how-to-use-application-object-of-android
Siwei Shen 申思维

2
configuration.locateist veraltet, setLocale benötigt API 17+ und updateConfiguration ist veraltet
Zoe

19

Nach diesem Artikel . Sie müssen den LocaleHelper.javain diesem Artikel genannten Download herunterladen .

  1. Erstellen Sie eine MyApplicationKlasse, die erweitert wirdApplication
  2. Überschreiben attachBaseContext(), um die Sprache zu aktualisieren.
  3. Registrieren Sie diese Klasse im Manifest.

    public class MyApplication extends Application {
       @Override
       protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
       }
    }
    
    <application
         android:name="com.package.MyApplication"
         .../>
  4. Erstellen BaseActivityund überschreiben onAttach(), um die Sprache zu aktualisieren. Wird für Android 6+ benötigt

    public class BaseActivity extends Activity {
      @Override
      protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
      }
    }
  5. Machen Sie alle Aktivitäten in Ihrer App erstreckt sich von BaseActivity.

    public class LocaleHelper {
    
    private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
    
    public static Context onAttach(Context context) {
        String lang = getPersistedData(context, Locale.getDefault().getLanguage());
        return setLocale(context, lang);
    }
    
    public static Context onAttach(Context context, String defaultLanguage) {
        String lang = getPersistedData(context, defaultLanguage);
        return setLocale(context, lang);
    }
    
    public static String getLanguage(Context context) {
        return getPersistedData(context, Locale.getDefault().getLanguage());
    }
    
    public static Context setLocale(Context context, String language) {
        persist(context, language);
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return updateResources(context, language);
        }
    
        return updateResourcesLegacy(context, language);
    }
    
    private static String getPersistedData(Context context, String defaultLanguage) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
    }
    
    private static void persist(Context context, String language) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
    
        editor.putString(SELECTED_LANGUAGE, language);
        editor.apply();
    }
    
    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
    
        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);
    
        return context.createConfigurationContext(configuration);
    }
    
    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(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;
    }
    }

kann super.attachBaseContext (LocaleHelper.onAttach (newBase)) nicht verwenden, da ich bereits super.attachBaseContext (CalligraphyContextWrapper.wrap (newBase)) verwende
Rasel

1
Sie können miteinander wickeln. super.attachBaseContext (CalligraphyContextWrapper.wrap (LocaleHelper.onAttach (newBase)))
Yeahia2508

15

Ich füge nur ein zusätzliches Stück hinzu, das mich auslöste.

Während die anderen Antworten zum Beispiel mit "de" gut funktionieren

String lang = "de";
Locale locale = new Locale(lang); 
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
    getBaseContext().getResources().getDisplayMetrics());

Das obige funktioniert nicht mit beispielsweise dem "fr_BE"Gebietsschema, sodass der values-fr-rBEOrdner oder ähnliches verwendet wird.

Benötigt die folgende geringfügige Änderung, um damit zu arbeiten "fr_BE"

String lang = "fr";

//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);

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

1
wenn Sie möchten , locale Änderung des aktuellen geöffnete Aktivität Anruf anzuwendenactivity.recreate()
Um Kra

Ich weiß, dass ich zu spät zur Party komme, aber das neue Gebietsschema (lang, country) war alles, was ich brauchte!
Jacob Holloway

activity.recreate () wie es funktioniert oder wenn wir dies nennen, dann String lang = "fr"; String country = "BE"; wird niemals überschreiben, wie es laufen wird
Amitsharma

Was ist mit der Verwendung, android.content.res.Configuration conf = res.getConfiguration();anstatt eine neue ConfigurationInstanz zu erstellen ? Gibt es einen Vorteil für die Verwendung eines neuen?
Bianca Daniciuc

14

Ich bin für die deutsche Sprache geändert, damit meine App selbst startet.

Hier ist mein korrekter Code. Jeder möchte das gleiche für mich verwenden .. (Wie man die Sprache in Android programmgesteuert ändert)

Mein Code:

Configuration config ; // variable declaration in globally

// this part is given inside onCreate Method starting and before setContentView()

public void onCreate(Bundle icic) 
{
    super.onCreate(icic);
    config = new Configuration(getResources().getConfiguration());
    config.locale = Locale.GERMAN ;
    getResources().updateConfiguration(config,getResources().getDisplayMetrics());

    setContentView(R.layout.newdesign);
}

1
@harikrishnan Es funktioniert nicht für mich und die Tastatur ändert sich nicht in die angegebene Sprache. Wie haben Sie die Aktivität im Manifest deklariert?
Avadhani Y

13

Ich weiß, dass es spät ist zu antworten, aber ich habe diesen Artikel hier gefunden . Das erklärt den gesamten Prozess sehr gut und bietet Ihnen einen gut strukturierten Code.

Gebietsschema Helferklasse:

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;

/**
 * This class is used to change your application locale and persist this change for the next time
 * that your app is going to be used.
 * <p/>
 * You can also change the locale of your application on the fly by using the setLocale method.
 * <p/>
 * Created by gunhansancar on 07/10/15.
 */
public class LocaleHelper {

    private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";

    public static Context onAttach(Context context) {
        String lang = getPersistedData(context, Locale.getDefault().getLanguage());
        return setLocale(context, lang);
    }

    public static Context onAttach(Context context, String defaultLanguage) {
        String lang = getPersistedData(context, defaultLanguage);
        return setLocale(context, lang);
    }

    public static String getLanguage(Context context) {
        return getPersistedData(context, Locale.getDefault().getLanguage());
    }

    public static Context setLocale(Context context, String language) {
        persist(context, language);

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

        return updateResourcesLegacy(context, language);
    }

    private static String getPersistedData(Context context, String defaultLanguage) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
    }

    private static void persist(Context context, String language) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();

        editor.putString(SELECTED_LANGUAGE, language);
        editor.apply();
    }

    @TargetApi(Build.VERSION_CODES.N)
    private static Context updateResources(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        Configuration configuration = context.getResources().getConfiguration();
        configuration.setLocale(locale);
        configuration.setLayoutDirection(locale);

        return context.createConfigurationContext(configuration);
    }

    @SuppressWarnings("deprecation")
    private static Context updateResourcesLegacy(Context context, String language) {
        Locale locale = new Locale(language);
        Locale.setDefault(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;
    }
}

Sie müssen attachBaseContext überschreiben und LocaleHelper.onAttach () aufrufen, um die Gebietsschemaeinstellungen in Ihrer Anwendung zu initialisieren.

import android.app.Application;
import android.content.Context;

import com.gunhansancar.changelanguageexample.helper.LocaleHelper;

public class MainApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
    }
}

Alles was Sie tun müssen, ist hinzuzufügen

LocaleHelper.onCreate(this, "en");

wo immer Sie das Gebietsschema ändern möchten.


LocaleHelper ist eine Klasse aus dem Artikel. Bei Links besteht die Gefahr, dass sie entfernt werden. Bitte fügen Sie den Code in Ihre Antwort ein.
Zoe

Ich möchte meine App nicht neu starten, da die App eine Aufgabe wie den Aufnahmebildschirm ausführt.
PriyankaChauhan

1
@PriyankaChauhan Ich denke, dass der Artikel diesen Fall behandelt: Sie haben zwei Möglichkeiten, das aktuell sichtbare Layout zu aktualisieren: Erstens können Sie den Text oder andere sprachabhängige Ressourcen einzeln aktualisieren.
Maksim Turaev

createConfigurationContext
Vielen

1
onCreate oder onAttach zum Aufrufen?
vanste25

12

Erstellen einer Klasse Erweitert Applicationund erstellt eine statische Methode. Dann können Sie diese Methode in allen Aktivitäten vorher aufrufen setContentView().

public class MyApp extends Application {

@Override
public void onCreate() {
    super.onCreate();
}

public static void setLocaleFa (Context context){
    Locale locale = new Locale("fa"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

public static void setLocaleEn (Context context){
    Locale locale = new Locale("en_US"); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    context.getApplicationContext().getResources().updateConfiguration(config, null);
}

}

Verwendung in Aktivitäten:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyApp.setLocaleFa(MainActivity.this);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
}

10

Für Android 7.0 Nougat (und niedriger) folgen Sie diesem Artikel:

Ändern Sie die Sprache programmgesteuert in Android

Alte Antwort
Dies beinhaltet RTL / LTR-Unterstützung:

public static void changeLocale(Context context, Locale locale) {
    Configuration conf = context.getResources().getConfiguration();
    conf.locale = locale;
    Locale.setDefault(locale);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
       conf.setLayoutDirection(conf.locale);
    }

    context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics());
}

1
updateConfiguration ist veraltet. Der Link ist nützlich, bitte fügen Sie ihn Ihrer Antwort hinzu. (Nur-Link-Antworten sind nicht gut, da der Link möglicherweise entfernt wird. In diesem Fall ist diese Antwort nutzlos.)
Zoe

8

Die einzige Lösung, die für mich vollständig funktioniert, ist eine Kombination aus Alex Volovoys Code und einem Neustart der Anwendung:

void restartApplication() {
    Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MainTabActivity.context.startActivity(i);
}


/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        startActivityForResult(new Intent(this, MainTabActivity.class), 0);         
    }
}

2
Nach dem Gebietsschemawechsel können Sie auch anrufenactivity.recreate()
An Kra

1
Ich möchte meine App nicht neu starten, da die App eine Aufgabe wie den Aufnahmebildschirm ausführt. Also ohne Neustart der App gibt es eine Lösung für Android 7.0
PriyankaChauhan

7

Ich stand vor dem gleichen Problem. Auf GitHub habe ich die Android-LocalizationActivity-Bibliothek gefunden .

Diese Bibliothek macht es sehr einfach, die Sprache Ihrer App zur Laufzeit zu ändern, wie Sie im folgenden Codebeispiel sehen können. Ein Beispielprojekt mit dem folgenden Beispielcode und weiteren Informationen finden Sie auf der Github-Seite.

Die LocalizationActivity erweitert AppCompatActivity, sodass Sie sie auch verwenden können, wenn Sie Fragmente verwenden.

public class MainActivity extends LocalizationActivity implements View.OnClickListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);

        findViewById(R.id.btn_th).setOnClickListener(this);
        findViewById(R.id.btn_en).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_en) {
            setLanguage("en");
        } else if (id == R.id.btn_th) {
            setLanguage("th");
        }
    }
}

7

Zeit für ein fälliges Update.

Zunächst die veraltete Liste mit der API, in der sie veraltet war:

  • configuration.locale (API 17)
  • updateConfiguration(configuration, displaymetrics) (API 17)

Das, was in letzter Zeit nicht richtig beantwortet wurde, ist die Verwendung der neuen Methode .

createConfigurationContext ist die neue Methode für updateConfiguration.

Einige haben es eigenständig wie folgt verwendet:

Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);

... aber das geht nicht. Warum? Die Methode gibt einen Kontext zurück, der dann zur Verarbeitung von Strings.xml-Übersetzungen und anderen lokalisierten Ressourcen (Bilder, Layouts usw.) verwendet wird.

Die richtige Verwendung ist wie folgt:

Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context  = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();

Wenn Sie dies gerade in Ihre IDE kopiert haben, wird möglicherweise eine Warnung angezeigt, dass die API erfordert, dass Sie auf API 17 oder höher abzielen. Dies kann umgangen werden, indem Sie es in eine Methode einfügen und die Anmerkung hinzufügen@TargetApi(17)

Aber warte. Was ist mit den älteren APIs?

Sie müssen eine andere Methode mit updateConfiguration ohne die TargetApi-Annotation erstellen.

Resources res = YourApplication.getInstance().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("th");
res.updateConfiguration(conf, dm);

Sie müssen hier keinen Kontext zurückgeben.

Jetzt kann es schwierig sein, diese zu verwalten. In API 17+ benötigen Sie den erstellten Kontext (oder die Ressourcen aus dem erstellten Kontext), um die entsprechenden Ressourcen basierend auf der Lokalisierung zu erhalten. Wie gehst du damit um?

Nun, so mache ich das:

/**
 * Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
 * @param lang language code (e.g. en_US)
 * @return the context
 * PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
 */
public Context setLanguage(String lang/*, Context c*/){
    Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed)
    int API = Build.VERSION.SDK_INT;
    if(API >= 17){
        return setLanguage17(lang, c);
    }else{
        return setLanguageLegacy(lang, c);
    }
}

/**
 * Set language for API 17
 * @param lang
 * @param c
 * @return
 */
@TargetApi(17)
public Context setLanguage17(String lang, Context c){
    Configuration overrideConfiguration = c.getResources().getConfiguration();
    Locale locale = new Locale(lang);
    Locale.setDefault(locale);
    overrideConfiguration.setLocale(locale);
    //the configuration can be used for other stuff as well
    Context context  = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
    //Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
    return context;
}

public Context setLanguageLegacy(String lang, Context c){
    Resources res = c.getResources();
    // Change locale settings in the app.
    DisplayMetrics dm = res.getDisplayMetrics();//Utility line
    android.content.res.Configuration conf = res.getConfiguration();

    conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
    Locale.setDefault(conf.locale);
    res.updateConfiguration(conf, dm);

    //Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
    //target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
    //supplied for both things
    return c;
}

Dieser Code verfügt über eine Methode, die basierend auf welcher API die entsprechende Methode aufruft. Dies ist etwas, was ich mit vielen verschiedenen veralteten Aufrufen gemacht habe (einschließlich Html.fromHtml). Sie haben eine Methode, die die erforderlichen Argumente aufnimmt, die sie dann in eine von zwei (oder drei oder mehr) Methoden aufteilt und das entsprechende Ergebnis basierend auf der API-Ebene zurückgibt. Es ist flexibel, da Sie nicht mehrmals prüfen müssen. Die "Eingabemethode" erledigt dies für Sie. Die Eingabemethode hier istsetLanguage

BITTE LESEN SIE DIESES, BEVOR SIE ES VERWENDEN

Sie müssen den zurückgegebenen Kontext verwenden, wenn Sie Ressourcen erhalten. Warum? Ich habe hier andere Antworten gesehen, die createConfigurationContext verwenden und den zurückgegebenen Kontext nicht verwenden. Damit es so funktioniert, muss updateConfiguration aufgerufen werden. Welches ist veraltet. Verwenden Sie den von der Methode zurückgegebenen Kontext, um Ressourcen abzurufen.

Anwendungsbeispiel :

Konstruktor oder ähnliches:

ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future)

Und wo immer Sie Ressourcen erhalten möchten, tun Sie Folgendes:

String fromResources = ctx.getString(R.string.helloworld);

Die Verwendung eines anderen Kontexts wird dies (theoretisch) aufheben.

AFAIK Sie müssen immer noch einen Aktivitätskontext verwenden, um Dialoge oder Toasts anzuzeigen. Dafür können Sie eine Instanz einer Aktivität verwenden (wenn Sie sich außerhalb befinden).


Verwenden Sie schließlich recreate()die Aktivität, um den Inhalt zu aktualisieren. Verknüpfung, um keine Aktualisierungsabsicht erstellen zu müssen.


1
Einige fragen sich vielleicht, ob der erstellte Kontext Ihren Speicher kostet. Laut offizieller Android-Dokumentation: "Jeder Aufruf dieser Methode gibt eine neue Instanz eines Kontextobjekts zurück. Kontextobjekte werden nicht gemeinsam genutzt. Der allgemeine Status (ClassLoader, andere Ressourcen für dieselbe Konfiguration) kann jedoch so sein, dass der Kontext selbst fair sein kann Leicht." Ich denke, Android erwartet von Ihnen, dass Sie ein separates Kontextobjekt für Gebietsschemas verwenden.
Sira Lam

7

Wenn du schreibst

android:configChanges="locale"

In jeder Aktivität (in der Manifestdatei) muss sie dann nicht bei jeder Eingabe festgelegt werden Activity.


11
Wenn es im Manifest ist, wie stellt dies dann eine Änderung zur Laufzeit dar, die anscheinend das war, was das OP wollte?
user316117

1
@ user316117 Es zeigt Android an, dass die App alle Angelegenheiten bezüglich der Gebietsschemakonfiguration intern behandelt und nicht, dass das Gebietsschema statisch ist. Ich bin mir nicht sicher, ob dies Android daran hindern würde, das Gebietsschema beim Wechsel zwischen Aktivitäten festzulegen, da ich nur gesehen habe, wie configChangesein Hack verwendet wird, um den Aktivitätsstatus bei Rotationen / etc.
JAB

Wie stelle ich die Sprache nur auf Englisch ein?
Kaveesh Kanwal

1
... bis Android Ihre Aktivität beendet, weil es mehr RAM benötigt
Louis CAD

@Brijesh Wenn wir die App-Sprache geändert haben, wenn wir eine Suchoption innerhalb der App haben und wenn wir danach suchen, wie die App Daten anzeigt, sollten wir für jede Sprache eine andere Datenbank entwickeln oder eine Android-Code-Einstellung vorhanden sein diese App könnte Daten nach Suche anzeigen?
Vishwa Pratap

5
Locale locale = new Locale("en");
Locale.setDefault(locale);

Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);

Wichtiges Update:

context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());

Beachten Sie, dass Sie im SDK> = 21 'Resources.updateConfiguration ()' aufrufen müssen , da sonst die Ressourcen nicht aktualisiert werden.


updateConfiguration ist veraltet. AFAIK Sie verwenden createConfigurationContext und wenden den Kontext an, den Sie darauf haben ( Context ctx = createConfigurationContext(args);und erhalten Ressourcen daraus
Zoe

Ich weiß, dass es veraltet ist. Trotzdem kenne ich keine Lösung, die auf Android 5 und höher funktioniert.
19аксим Петлюк

Dann haben Sie den Javadoc eindeutig nicht überprüft. Sie rufen den aus createConfigurationContext erstellten Kontext auf
Zoe

Ok, aber trotzdem sollten wir updateConfiguration () aufrufen, oder?
19аксим Петлюк

1
Verwenden Sie den veralteten Anruf nicht. Das heißt, kein Aufruf von updateConfiguration
Zoe

4
/*change language at Run-time*/
//use method like that:
//setLocale("en");
 public void setLocale(String lang) { 
  myLocale = new Locale(lang);         
  Resources res = getResources();         
  DisplayMetrics dm = res.getDisplayMetrics();         
  Configuration conf = res.getConfiguration();         
  conf.locale = myLocale;         
  res.updateConfiguration(conf, dm);         
  Intent refresh = new Intent(this, AndroidLocalize.class);         
  startActivity(refresh); 
 }

5
Keine Notwendigkeit, neue Aktivität zu starten, aktualisieren Sie einfach die aktuelleactivity.recreate()
To Kra

4

Locale configurationsollte activityvor dem Einstellen des Inhalts jeweils eingestellt werden -this.setContentView(R.layout.main);


Aber was ist, wenn Sie es im laufenden Betrieb umschalten möchten, nachdem setContentView () aufgerufen wurde?
IgorGanapolsky

2
Nach dem Gebietsschemawechsel können Sie auch anrufenactivity.recreate()
An Kra

4

Erstellen Sie zunächst multi string.xml für verschiedene Sprachen. Verwenden Sie dann diesen Codeblock in der onCreate()Methode:

super.onCreate(savedInstanceState);
String languageToLoad  = "fr"; // change your language here
Locale locale = new Locale(languageToLoad); 
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, 
  getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);

Vielen Dank, dieser Code funktioniert
super

4

Hier ist ein Code, der für mich funktioniert:

public class  MainActivity extends AppCompatActivity {
    public static String storeLang;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
        storeLang = shp.getString(getString(R.string.key_lang), "");

        // Create a new Locale object
        Locale locale = new Locale(storeLang);

        // Create a new configuration object
        Configuration config = new Configuration();
        // Set the locale of the new configuration
        config.locale = locale;
        // Update the configuration of the Accplication context
        getResources().updateConfiguration(
                config,
                getResources().getDisplayMetrics()
        );

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Quelle: hier


3

Keine der hier aufgeführten Lösungen hat mir geholfen.

Die Sprache hat android> = 7.0 nicht eingeschaltet, wenn AppCompatDelegate.setDefaultNightMode (AppCompatDelegate.MODE_NIGHT_YES)

Dieses LocaleUtils funktioniert einwandfrei: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe

LocaleUtils

public class LocaleUtils {

public static final String LAN_SPANISH      = "es";
public static final String LAN_PORTUGUESE   = "pt";
public static final String LAN_ENGLISH      = "en";

private static Locale sLocale;

public static void setLocale(Locale locale) {
    sLocale = locale;
    if(sLocale != null) {
        Locale.setDefault(sLocale);
    }
}

public static void updateConfig(ContextThemeWrapper wrapper) {
    if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        Configuration configuration = new Configuration();
        configuration.setLocale(sLocale);
        wrapper.applyOverrideConfiguration(configuration);
    }
}

public static void updateConfig(Application app, Configuration configuration) {
    if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        //Wrapping the configuration to avoid Activity endless loop
        Configuration config = new Configuration(configuration);
        config.locale = sLocale;
        Resources res = app.getBaseContext().getResources();
        res.updateConfiguration(config, res.getDisplayMetrics());
    }
}
}

Dieser Code wurde zur Anwendung hinzugefügt

public class App extends Application {
public void onCreate(){
    super.onCreate();

    LocaleUtils.setLocale(new Locale("iw"));
    LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    LocaleUtils.updateConfig(this, newConfig);
}
}

Code in Aktivität

public class BaseActivity extends AppCompatActivity {
    public BaseActivity() {
        LocaleUtils.updateConfig(this);
    }
}

2

Die Antwort von Alex Volovoy funktioniert nur, wenn sie in der onCreate-Methode der Aktivität enthalten ist.

Die Antwort, die in allen Methoden funktioniert, befindet sich in einem anderen Thread

Ändern Sie die Sprache programmgesteuert in Android

Hier ist die Anpassung des Codes



    Resources standardResources = getBaseContext().getResources();

    AssetManager assets = standardResources.getAssets();

    DisplayMetrics metrics = standardResources.getDisplayMetrics();

    Configuration config = new Configuration(standardResources.getConfiguration());

    config.locale = new Locale(languageToLoad);

    Resources defaultResources = new Resources(assets, metrics, config);

Hoffe, dass es hilft.


19
Sie sagten "Die Antwort, die in allen Methoden funktioniert, ist in einem anderen Thread", aber Ihr Link zeigt auf DIESEN Thread! "
user316117

1
config.locale ist veraltet
Zoe

2
rekursive Antwort, möglich von StackOverflow
tamtom

2

Beachten Sie, dass diese Lösung updateConfiguration mit der Android M- Version in einigen Wochen nicht mehr funktioniert . Die neue Methode hierfür ist jetzt die Verwendung der applyOverrideConfigurationMethode aus dem ContextThemeWrapper API-Dokument

Meine vollständige Lösung finden Sie hier, da ich selbst mit dem Problem konfrontiert war: https://stackoverflow.com/a/31787201/2776572


Ich versuche den updateConfiguration-Code auf Android 6.0.1 und er funktioniert einwandfrei. Ich weiß nicht, ob Google dies behoben hat, aber ich kann ihn ohne Probleme verwenden
innovaciones

1
@innovaciones veraltete Methoden gibt es schon eine Weile. Schließlich wird es entfernt. Es dauert lange, aber es ist am besten, so schnell wie möglich auf die neuen APIs umzusteigen, um Probleme auf der
Zoe

1

Es gibt einige Schritte, die Sie implementieren sollten

Zunächst müssen Sie das Gebietsschema Ihrer Konfiguration ändern

Resources resources = context.getResources();

Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);

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

Zweitens, wenn Sie möchten, dass Ihre Änderungen direkt auf das sichtbare Layout angewendet werden, können Sie entweder die Ansichten direkt aktualisieren oder einfach activity.recreate () aufrufen, um die aktuelle Aktivität neu zu starten.

Außerdem müssen Sie Ihre Änderungen beibehalten, da Sie nach dem Schließen Ihrer Anwendung durch den Benutzer die Sprachänderung verlieren würden.

Eine ausführlichere Lösung habe ich in meinem Blogbeitrag " Sprache programmgesteuert in Android ändern" erklärt

Grundsätzlich rufen Sie einfach LocaleHelper.onCreate () in Ihrer Anwendungsklasse auf. Wenn Sie das Gebietsschema im laufenden Betrieb ändern möchten, können Sie LocaleHelper.setLocale () aufrufen.


@LunarWatcher Ja, wenn Sie den Code tatsächlich auf github oder gist überprüfen, wird er bereits verarbeitet.
Gunhan

1

Dies funktioniert, wenn ich die Taste drücke, um die Textsprache meiner Textansicht zu ändern. (Strings.xml im Ordner values-de)

String languageToLoad = "de"; // your language
Configuration config = getBaseContext().getResources().getConfiguration();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
recreate();

1

Fügen Sie die LocaleHelper- Klasse hinzu

public class LocaleHelper{ 
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
    String lang = getPersistedData(context, Locale.getDefault().getLanguage());
    return setLocale(context, lang);
}

public static Context onAttach(Context context, String defaultLanguage) {
    String lang = getPersistedData(context, defaultLanguage);
    return setLocale(context, lang);
}

public static String getLanguage(Context context) {
    return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
    persist(context, language);

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

    return updateResourcesLegacy(context, language);
}

private static String getPersistedData(Context context, String defaultLanguage) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}

private static void persist(Context context, String language) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();

    editor.putString(SELECTED_LANGUAGE, language);
    editor.apply();
}

@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);

    Configuration configuration = context.getResources().getConfiguration();
    configuration.setLocale(locale);
    configuration.setLayoutDirection(locale);

    return context.createConfigurationContext(configuration);
}

@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(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;
}
}

In Aktivität oder Fragment

Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();

Jetzt SetText für jeden Text

TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));

0

ähnlich der akzeptierten beantworteten, aber 2017-Version und hinzugefügtem Neustart (ohne Neustart rendert die nächste Aktivität manchmal immer noch Englisch):

// Inside some activity...
private void changeDisplayLanguage(String langCode) {
// Step 1. Change the locale in the app's configuration
    Resources res = getResources();
    android.content.res.Configuration conf = res.getConfiguration();
    conf.setLocale(currentLocale);
    createConfigurationContext(conf);
// Step 2. IMPORTANT! you must restart the app to make sure it works 100%
    restart();
}
private void restart() {
    PackageManager packageManager = getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
    ComponentName componentName = intent.getComponent();
    Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
    mainIntent.putExtra("app_restarting", true);
    PrefUtils.putBoolean("app_restarting", true);
    startActivity(mainIntent);
    System.exit(0);
}

1) Verwenden Sie stattdessen finish () 2), um die App neu zu starten. activity.recreate()3) Der zurückgegebene Kontext muss meiner Meinung nach verwendet werden, um die Ressourcen
abzurufen

Ich möchte meine App nicht neu starten, da die App eine Aufgabe wie den Aufnahmebildschirm ausführt.
PriyankaChauhan

0

Zuerst erstellen Sie Verzeichnisnamenwerte - "Sprachname" wie Hindi, als "hi" zu schreiben und denselben String-Dateinamen in dieses Verzeichnis zu kopieren und den Wert zu ändern. Ändern Sie den Parameter nicht, nachdem Sie den folgenden Code in Ihrer Aktion wie Schaltfläche usw. festgelegt haben.

Locale myLocale = new Locale("hi");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(Home.this, Home.class);
startActivity(refresh);
finish(); 

1
conf.localeist veraltet
Zoe

0
private void setLanguage(String language) {
    Locale locale = new Locale(language);
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        config.setLocale(locale);
    } else {
        config.locale = locale;
    }
    getResources().updateConfiguration(config,
            getResources().getDisplayMetrics());

}

1
Ich möchte meine App nicht neu starten, da die App eine Aufgabe wie den Aufnahmebildschirm ausführt.
PriyankaChauhan

Ja, auf 6.0 funktioniert es gut für mich, ohne App neu zu starten, Sprache geändert, aber ich habe nicht auf 7.0 getestet
Adeeb Karim

0

Im Beispiel stellen wir die englische Sprache ein:

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

Bitte denken Sie daran, dass dies nur funktioniert, wenn die Sprache auch im Gerätesystem gefunden wird, nicht nur in der Anwendung


0

Für Arabisch / RTL-Unterstützung

  1. Sie müssen Ihre Spracheinstellungen über - attachBaseContext () aktualisieren.
  2. Für Android Version N und höher müssen Sie createConfigurationContext () & updateConfiguration () verwenden - andernfalls funktioniert das RTL-Layout nicht ordnungsgemäß

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

    public Context updateBaseContextLocale(Context context) {
        String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
        if (language == null || language.isEmpty()) {
            //when first time enter into app (get the device language and set it
            language = Locale.getDefault().getLanguage();
            if (language.equals("ar")) {
                SharedPreference.getInstance().save(mContext, "lan", "ar");
            }
        }
        Locale locale = new Locale(language);
        Locale.setDefault(locale);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            updateResourcesLocale(context, locale);
            return  updateResourcesLocaleLegacy(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;
    }

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.