web-dev-qa-db-ja.com

変更方法Android O / Oreo / api 26 app language

アプリの言語を変更したいのですが、これはAPI 26まで正常に機能します。

Api> 25の場合、Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);setContentView(R.layout.activity_main);の前に置きますが、何も変わりません。

docs はこれについてあまり説明しません。

Yes in Android Oreoローカリゼーションはupdateconfigurationでうまく機能しません。しかし、非推奨ですAndroid N自体。私のためにうまく働いています。これを試してください...

アクティビティでこれを追加します。

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

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

私は同じ問題を抱えていました:Android 8.0+私のアプリの一部はもはや言語を変更しませんでした。アプリケーションとアクティビティコンテキストの両方の更新は私を助けます。

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

updateConfigurationは非推奨です。createConfigurationContextを使用する必要があります。私はこのように解決しました:

    @Override
    protected void attachBaseContext(Context newBase) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Configuration config = newBase.getResources().getConfiguration();
            //Update your config with the Locale i. e. saved in SharedPreferences
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(newBase);
            String language = prefs.getString(SP_KEY_LANGUAGE, "en_US");
            Locale.setDefault(locale);
            config.setLocale(new Locale(language));
            newBase = newBase.createConfigurationContext(config);
        }
        super.attachBaseContext(newBase);
    }
7
Luke

すべての人に更新Android Oreoまでのバージョン

このようなクラスを作成します

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

}

アプリから言語を選択したら、次のように言語コードを共有設定に保存します

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

これらの3つの関数は、Utiltiyクラス(好み)内に記述する必要があります。次に、アプリからアプリの言語を選択したら、setSelectedLanguageId()関数を呼び出して、言語IDをパラメーターとして渡します。

このようにして、選択した言語をアプリに保存しました。アプリケーションクラスで次のような関数を記述します

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

ここで、PreferenceUtilは私のUtiltiyクラスです。ユーティリティクラス関数に置き換える必要があります。

また、アプリケーションクラスに変数を作成する必要があります

private static Application applicationInstance;

applicationクラスのonCreateメソッドで、applicationInstanceをこのようなアプリケーションコンテキストに初期化します

applicationInstance = this; 

次に、アプリケーションクラスにゲッター関数を記述します

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

そして、最初のアクティビティを開始するとき、アクティビティのonCreateでこのメソッドを呼び出します

Application.getInstance().initAppLanguage(this);

アクティビティのコンテキストを、アプリケーションコンテキストではなく、initAppLanguage()関数に渡していることに注意してください。アプリケーションコンテキストを渡すことは、Oreo(私にとっては少なくとも)で動作しません。

したがって、言語を選択したら、アプリケーションを完全に再起動してください。あなたはこれを達成することができます

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

startActivity(i);

これがあなたを助けることを願っています!

3
emilpmp

可能ですが、プログラムで言語を設定することはお勧めしません

AndroidはシステムUIとアプリの言語が同じになるように設計されています。プログラムで変更すると、システムと戦うことになります。

代わりに、異なるstrings.xml言語を追加して多言語サポートを有効にすることで、言語が自動的に変更されます

このGoogle Developersの記事を読むことをお勧めします。

異なる言語と文化のサポート

プログラムで変更する必要がある場合は、次を実行できます。

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

SDK> = 21では、 'Resources.updateConfiguration()'を呼び出す必要があります。そうしないと、リソースは更新されません。

それが役に立てば幸い。

2
Andre Breton

これは、キットカット、ロリポップ、マシュマロ、ヌガー、オレオでも機能する完全なソリューションです。以下のすべての手順に従ってください。

最初にJava以下のようなクラスを作成します

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

ロケールを変更したい場所のボタンクリックでこのスニペットを追加します

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

最後に、以下のコードをスプラッシュアクティビティまたは起動アクティビティに貼り付けます。

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    String lang = preferences.getString("lang", "");
    boolean langSelected = preferences.getBoolean("langSelected", false);
    SharedPreferences.Editor editor = preferences.edit();
    if (langSelected) {
        editor.clear();
        editor.putString("lang", lang);
        editor.putBoolean("langSelected", true);
        editor.apply();
        LocaleUtils.updateConfig(this,lang);
    } else {
        LocaleUtils.updateConfig(this, Locale.getDefault().getLanguage());
        editor.clear();
        editor.putString("lang", Locale.getDefault().getLanguage());
        editor.putBoolean("langSelected", false);
        editor.apply();
    }
1
Ness Tyagi

getApplicationContext()の代わりにgetContext()を使用する必要があります

すべてのソースですべてのソリューションを使用した後、最終的に問題が見つかりました。それは私を2日間怒らせます。

Android Oreo(API 26)ではcreateConfigurationContextを使用する必要があることを誰もが知っていますが、私の問題はローカルで国名を使用しています。

交換

en_USwithen

ar_AEwithar

fa_IRwithfa

そして、私の問題は解決しました。

誰かを助けたい

0
Radesh