ちょうど最近context.getResources(). pdateConfiguration() はAndroid API 25で非推奨になりました。コンテキストを使用することをお勧めします。 createConfigurationContext() 。
createConfigurationContext を使用してAndroidシステムロケールをオーバーライドする方法を知っている人はいますか?
これが行われる前に:
Configuration config = getBaseContext().getResources().getConfiguration();
config.setLocale(locale);
context.getResources().updateConfiguration(config,
context.getResources().getDisplayMetrics());
書道 に触発されて、コンテキストラッパーを作成することになりました。私の場合、システム言語を上書きしてアプリユーザーにアプリ言語を変更するオプションを提供する必要がありますが、これは実装する必要のあるロジックでカスタマイズできます。
import Android.annotation.TargetApi;
import Android.content.Context;
import Android.content.ContextWrapper;
import Android.content.res.Configuration;
import Android.os.Build;
import Java.util.Locale;
public class MyContextWrapper extends ContextWrapper {
public MyContextWrapper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ContextWrapper wrap(Context context, String language) {
Configuration config = context.getResources().getConfiguration();
Locale sysLocale = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sysLocale = getSystemLocale(config);
} else {
sysLocale = getSystemLocaleLegacy(config);
}
if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setSystemLocale(config, locale);
} else {
setSystemLocaleLegacy(config, locale);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
context = context.createConfigurationContext(config);
} else {
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
return new MyContextWrapper(context);
}
@SuppressWarnings("deprecation")
public static Locale getSystemLocaleLegacy(Configuration config){
return config.locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static Locale getSystemLocale(Configuration config){
return config.getLocales().get(0);
}
@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale){
config.locale = locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale){
config.setLocale(locale);
}
}
ラッパーを挿入するには、すべてのアクティビティで次のコードを追加します。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(MyContextWrapper.wrap(newBase,"fr"));
}
UPDATE 10/19/2018時々、向きの変更、またはアクティビティの一時停止/再開後に、構成オブジェクトがデフォルトのシステム構成にリセットされ、結果としてアプリが表示されますコンテキストをフランス語の「fr」ロケールでラップしていても、英語の「en」テキストを表示します。したがって、ベストプラクティスとして、アクティビティまたはフラグメントのグローバル変数にContext/Activityオブジェクトを保持しないでください。
さらに、MyBaseFragmentまたはMyBaseActivityで次を作成して使用します。
public Context getMyContext(){
return MyContextWrapper.wrap(getContext(),"fr");
}
このプラクティスは、100%バグのないソリューションを提供します。
おそらくこのように:
Configuration overrideConfiguration = getBaseContext().getResources().getConfiguration();
overrideConfiguration.setLocales(LocaleList);
Context context = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();
書道とムルジャンと私に触発され、私はこれを作成しました。
最初に、アプリケーションのサブクラスを作成する必要があります。
public class MyApplication extends Application {
private Locale locale = null;
@Override
public void onCreate() {
super.onCreate();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Configuration config = getBaseContext().getResources().getConfiguration();
String lang = preferences.getString(getString(R.string.pref_locale), "en");
String systemLocale = getSystemLocale(config).getLanguage();
if (!"".equals(lang) && !systemLocale.equals(lang)) {
locale = new Locale(lang);
Locale.setDefault(locale);
setSystemLocale(config, locale);
updateConfiguration(config);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (locale != null) {
setSystemLocale(newConfig, locale);
Locale.setDefault(locale);
updateConfiguration(newConfig);
}
}
@SuppressWarnings("deprecation")
private static Locale getSystemLocale(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return config.getLocales().get(0);
} else {
return config.locale;
}
}
@SuppressWarnings("deprecation")
private static void setSystemLocale(Configuration config, Locale locale) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(locale);
} else {
config.locale = locale;
}
}
@SuppressWarnings("deprecation")
private void updateConfiguration(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getBaseContext().createConfigurationContext(config);
} else {
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
}
}
次に、これをAndroidManifest.xmlアプリケーションタグに設定する必要があります。
<application
...
Android:name="path.to.your.package.MyApplication"
>
これをAndroidManifest.xmlアクティビティタグに追加します。
<activity
...
Android:configChanges="locale"
>
pref_localeは次のような文字列リソースであることに注意してください。
<string name="pref_locale">fa</string>
pref_localeが設定されていない場合、ハードコード「en」はデフォルトのlangです
コトリンの長所を備えた@ bassel-mourjanのソリューションは次のとおりです。
import Android.annotation.TargetApi
import Android.content.ContextWrapper
import Android.os.Build
import Java.util.*
@Suppress("DEPRECATION")
fun ContextWrapper.wrap(language: String): ContextWrapper {
val config = baseContext.resources.configuration
val sysLocale: Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.getSystemLocale()
} else {
this.getSystemLocaleLegacy()
}
if (!language.isEmpty() && sysLocale.language != language) {
val locale = Locale(language)
Locale.setDefault(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.setSystemLocale(locale)
} else {
this.setSystemLocaleLegacy(locale)
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val context = baseContext.createConfigurationContext(config)
ContextWrapper(context)
} else {
baseContext.resources.updateConfiguration(config, baseContext.resources.displayMetrics)
ContextWrapper(baseContext)
}
}
@Suppress("DEPRECATION")
fun ContextWrapper.getSystemLocaleLegacy(): Locale {
val config = baseContext.resources.configuration
return config.locale
}
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.getSystemLocale(): Locale {
val config = baseContext.resources.configuration
return config.locales[0]
}
@Suppress("DEPRECATION")
fun ContextWrapper.setSystemLocaleLegacy(locale: Locale) {
val config = baseContext.resources.configuration
config.locale = locale
}
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.setSystemLocale(locale: Locale) {
val config = baseContext.resources.configuration
config.setLocale(locale)
}
そして、これがあなたの使い方です:
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(ContextWrapper(newBase).wrap(defaultLocale.language))
}
これを試して:
Configuration config = getBaseContext().getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
contextWrapperを使用した簡単なソリューションがここにあります。 Android Nはプログラムで言語を変更します recreate()メソッドに注意