it-swarm.com.de

Programmgesteuertes Ändern der App-Sprache in Android

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

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

Ich möchte, dass der Benutzer die Sprache der App über die App ändert.

396
hpique

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 das Ändern der Sprache, haben uns jedoch dafür entschieden, die Benutzeroberfläche der Telefonbenutzeroberfläche anzupassen. Es funktionierte über das Setzen des Gebietsschemas, war aber zu fehlerhaft. Und Sie müssen es nach meiner Erfahrung jedes Mal einstellen, wenn Sie eine Aktivität (jede Aktivität) eingeben. Hier ist ein Code, falls du diesen noch brauchst (auch das empfehle ich 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 sprachspezifische Inhalte haben, können Sie diese basierend auf der Einstellung ändern.

340
Alex Volovoy

Es ist wirklich Arbeit:

fa = Persisch, en = Englisch

Geben Sie Ihren Sprachcode in die Variable languageToLoad 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);
  }
}
162
AliSh

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

  • der Benutzer sollte (mit Absicht) auf die Systemeinstellungen hingewiesen werden, um sie manuell zu ändern
  • die Anwendung sollte ihre Lokalisierung wie in der Antwort von Alex beschrieben selbstständig handhaben

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

Dies ist eine undokumentierte 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);
34
icyerasor

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

Erstellen Sie zunächst eine Basisaktivität und lassen Sie alle Ihre Aktivitäten darauf aufbauen:

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 wie oben ist.

Das ist alles! Ich hoffe das kann jemandem helfen.

30
Daniel S.

Ich fügte 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 dem Gebietsschema "fr_BE", sodass der Ordner values-fr-rBE oder ähnliches verwendet wird.

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

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

Nach dieser Artikel . Sie müssen LocaleHelper.Java herunterladen, auf das in diesem Artikel verwiesen wird.

  1. Erstelle MyApplication Klasse, die Application erweitert
  2. Überschreiben Sie 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 Sie BaseActivity und überschreiben Sie onAttach(), um die Sprache zu aktualisieren. Benötigt für Android 6 +

    _public class BaseActivity extends Activity {
      @Override
      protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
      }
    }
    _
  5. Alle Aktivitäten in Ihrer App können von BaseActivity aus erweitert werden.

    _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;
    }
    }
    _
14
Khaled Lela

Ich weiß, es ist spät zu antworten, aber ich fand dieser Artikel hier . Dies erklärt den gesamten Prozess sehr gut und liefert Ihnen einen gut strukturierten Code.

Locale Helper Klasse:

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.

13
Anirudh Sharma

Ich bin für die deutsche Sprache für meine App selbst gestartet.

Hier ist mein richtiger 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);
}
13
harikrishnan

Klasse erstellen Erweitert Application und erstellt eine statische Methode. Dann können Sie diese Methode in allen Aktivitäten vor setContentView() aufrufen.

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

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

Sprache in Android programmgesteuert ändern

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

Wenn du schreibst

Android:configChanges="locale"

In jeder Aktivität (in der Manifestdatei) muss sie dann nicht jedes Mal festgelegt werden, wenn Sie Activity eingeben.

8
Brijesh Masrani

Die einzige Lösung, die für mich vollständig funktioniert, ist eine Kombination aus Alex Volovoys Code und dem Mechanismus zum Neustart von Anwendungen:

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

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)

Was in letzter Zeit noch 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 das einfach in Ihre IDE kopiert haben, wird möglicherweise eine Warnung angezeigt, dass Sie für die API das Targeting auf API 17 oder höher benötigen. Dies kann umgangen werden, indem Sie es in eine Methode einfügen und die Annotation @TargetApi(17) hinzufügen.

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.

Nun 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 geeigneten Ressourcen basierend auf der Lokalisierung abzurufen. Wie gehst du damit um?

Nun, so mache ich es:

/**
 * Full locale list: https://stackoverflow.com/questions/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 funktioniert mit einer Methode, die basierend auf der jeweiligen 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 es nicht mehrmals überprüfen müssen. Die "Eintrag" -Methode erledigt dies für Sie. Die Eingabemethode hier ist setLanguage

BITTE LESEN SIE DIES, 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.

Beispielnutzung:

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 dann, 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) unterbrechen.

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 außerhalb sind)


Verwenden Sie abschließend recreate() für die Aktivität, um den Inhalt zu aktualisieren. Verknüpfung, um keine Absicht zum Aktualisieren zu erstellen.

5
Zoe

Ich hatte das gleiche 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.

LocalizationActivity erweitert AppCompatActivity, sodass Sie es 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");
        }
    }
}
5
Rockney

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

4
Til Schweiger

Localeconfiguration sollte in jedem activity eingestellt werden, bevor der Inhalt eingestellt wird - this.setContentView(R.layout.main);

4
cheskapac

Erstellen Sie zunächst die Datei 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);
4
Mohsen mokhtari
/*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); 
 }
4
altan yuksel

Beachten Sie, dass diese Lösung mit updateConfigurationwird mit dem Android M nicht mehr funktionieren in einigen Wochen verfügbar sein wird. Die neue Methode hierfür ist jetzt die applyOverrideConfiguration-Methode aus ContextThemeWrappersiehe API-Dokument

Sie können meine vollständige Lösung hier finden, da ich mich dem Problem selbst gestellt habe: https://stackoverflow.com/a/31787201/2776572

2
Xexiz

Alex Volovoy Antwort funktioniert nur bei mir, wenn es in der onCreate-Methode der Aktivität 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.

2
gmauri21

Dies funktioniert, wenn ich die Taste drücke, um die Textsprache meines TextView 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
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
Adeeb karim

ähnlich der akzeptierten, aber beantworteten Version von 2017 und hinzugefügtem Neustart (ohne Neustart wird manchmal die nächste Aktivität immer noch englisch wiedergegeben):

// 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);
}
0
ericn

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

Fügte diesen Code der Anwendung hinzu

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);
    }
}
0
Pavel Shirokov

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 beachten Sie, dass dies nur funktioniert, wenn die Sprache auch im Gerätesystem gefunden wird, nicht nur in der Anwendung

0
Pavel Pekki

Zuerst erstellen Sie Verzeichnisnamenwerte - "Sprachenname" wie Hindi, dann schreiben Sie "Hi" und kopieren den gleichen String-Dateinamen in dieses Verzeichnis und ändern den Wert nicht. Ändern Sie den Parameter nicht, nachdem Sie den folgenden Code in Ihrer Aktion festgelegt haben, wie z.

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(); 
0
Dhaval Shingala

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

Wenn Sie möchten, dass Ihre Änderungen direkt auf das angezeigte Layout angewendet werden, können Sie die Ansichten entweder 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 der Anwendung durch den Benutzer die Sprachänderung verlieren würden.

Ich habe eine detailliertere Lösung in meinem Blogbeitrag erklärt Sprache programmatisch in Android ändern

Grundsätzlich rufen Sie LocaleHelper.onCreate () in Ihrer Anwendungsklasse auf, und wenn Sie das Gebietsschema im Handumdrehen ändern möchten, können Sie LocaleHelper.setLocale () aufrufen.

0
Gunhan