如何更改Android O / Oreo / api 26 应用程序语言
How to change Android O / Oreo / api 26 app language
我想更改应用程序的语言,这在 API 26 之前都可以正常工作。
对于 api > 25 我把 Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
放在 setContentView(R.layout.activity_main);
之前但没有任何变化。
docs这个就不多解释了
可以,但我不建议以编程方式设置语言
Android 的设计使 系统 UI 和您的应用程序具有相同的语言,如果您以编程方式更改它,您将与系统发生冲突
相反,您可以通过添加不同的 strings.xml 语言来启用多语言支持,这将自动更改语言
我建议通读这篇 Google 开发人员 文章:
Supporting Different Languages and Cultures
如果您确实需要以编程方式更改它,您可以执行以下操作
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()',否则不会更新资源
希望对您有所帮助。
您需要使用 getApplicationContext()
而不是 getContext()
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);
}
这是适用于 kitkat、Lollipop、Marshmallow、Nougat 和 Oreo 的完整解决方案。只需按照以下所有步骤操作即可。
首先创建一个 java class 如下所示
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);
最后将下面的代码粘贴到 Splash Activity 或 Launching Activity 中。
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();
}
是 android 奥利奥本地化无法正常使用更新配置。但它在 android N 本身中已被弃用。在每个附加上下文中使用 createconfiguration 而不是 updateconfiguration。它对我来说很好用。试试这个...
在你activity添加这个..
@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);
}
更新所有 android 版本直到 Oreo
像这样创建一个class
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;
}
}
现在,当您 select 来自您的应用程序的语言时,将语言代码保存在共享首选项中,如下所示
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");
}
这三个函数应该写在一个Utiltiy里面class(你喜欢)。然后,当您从应用程序 select 应用程序语言时,调用 setSelectedLanguageId() 函数并将语言 ID 作为参数传递。
这样您就可以在您的应用程序中保存 selected 语言。现在在你的应用程序中 class 写一个这样的函数
public void initAppLanguage(Context context){
LocaleUtils.initialize(context, PreferenceUtil.getSelectedLanguageId() );
}
这里的 PreferenceUtil 是我的 Utiltiy class。您应该将其替换为实用程序 class 函数。
您还应该在您的应用程序中创建一个变量class
private static Application applicationInstance;
并在您的应用程序 class 的 onCreate 方法中,将 applicationInstance 初始化为这样的应用程序上下文
applicationInstance = this;
现在在你的应用程序中写一个getter函数class
public static synchronized Application getInstance() {
return applicationInstance;
}
现在,当您开始第一个 activity 时,请在 activity 的 onCreate
中调用此方法
Application.getInstance().initAppLanguage(this);
请记住,我们将 activity 的上下文传递给 initAppLanguage() 函数,而不是应用程序上下文。传递应用程序上下文不会使其在 Oreo 中工作(至少对我而言)。
因此,当您 select 语言尝试完全重新启动您的应用程序时。
您可以通过
实现
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
开始活动(i);
希望对您有所帮助!
我遇到了同样的问题:自从 Android 8.0+ 我的应用程序的某些部分不再更改其语言。更新应用程序和 activity 上下文对我有帮助。以下是 MainActivity 函数的示例:
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());
}
在使用所有来源的所有解决方案后,我终于找到了我的问题。这让我生气了2天。
大家都知道在Android Oreo (API 26) 中我们必须使用createConfigurationContext
,但我的问题是使用带有local 的Country name。
替换
en_US with en
ar_AE with ar
fa_IR 和 fa
我的问题解决了。
希望对某人有所帮助
我想更改应用程序的语言,这在 API 26 之前都可以正常工作。
对于 api > 25 我把 Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
放在 setContentView(R.layout.activity_main);
之前但没有任何变化。
docs这个就不多解释了
可以,但我不建议以编程方式设置语言
Android 的设计使 系统 UI 和您的应用程序具有相同的语言,如果您以编程方式更改它,您将与系统发生冲突
相反,您可以通过添加不同的 strings.xml 语言来启用多语言支持,这将自动更改语言
我建议通读这篇 Google 开发人员 文章:
Supporting Different Languages and Cultures
如果您确实需要以编程方式更改它,您可以执行以下操作
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()',否则不会更新资源
希望对您有所帮助。
您需要使用 getApplicationContext()
而不是 getContext()
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);
}
这是适用于 kitkat、Lollipop、Marshmallow、Nougat 和 Oreo 的完整解决方案。只需按照以下所有步骤操作即可。
首先创建一个 java class 如下所示
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);
最后将下面的代码粘贴到 Splash Activity 或 Launching Activity 中。
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();
}
是 android 奥利奥本地化无法正常使用更新配置。但它在 android N 本身中已被弃用。在每个附加上下文中使用 createconfiguration 而不是 updateconfiguration。它对我来说很好用。试试这个...
在你activity添加这个..
@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);
}
更新所有 android 版本直到 Oreo
像这样创建一个class
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;
}
}
现在,当您 select 来自您的应用程序的语言时,将语言代码保存在共享首选项中,如下所示
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");
}
这三个函数应该写在一个Utiltiy里面class(你喜欢)。然后,当您从应用程序 select 应用程序语言时,调用 setSelectedLanguageId() 函数并将语言 ID 作为参数传递。
这样您就可以在您的应用程序中保存 selected 语言。现在在你的应用程序中 class 写一个这样的函数
public void initAppLanguage(Context context){
LocaleUtils.initialize(context, PreferenceUtil.getSelectedLanguageId() );
}
这里的 PreferenceUtil 是我的 Utiltiy class。您应该将其替换为实用程序 class 函数。
您还应该在您的应用程序中创建一个变量class
private static Application applicationInstance;
并在您的应用程序 class 的 onCreate 方法中,将 applicationInstance 初始化为这样的应用程序上下文
applicationInstance = this;
现在在你的应用程序中写一个getter函数class
public static synchronized Application getInstance() {
return applicationInstance;
}
现在,当您开始第一个 activity 时,请在 activity 的 onCreate
中调用此方法Application.getInstance().initAppLanguage(this);
请记住,我们将 activity 的上下文传递给 initAppLanguage() 函数,而不是应用程序上下文。传递应用程序上下文不会使其在 Oreo 中工作(至少对我而言)。
因此,当您 select 语言尝试完全重新启动您的应用程序时。 您可以通过
实现Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
开始活动(i);
希望对您有所帮助!
我遇到了同样的问题:自从 Android 8.0+ 我的应用程序的某些部分不再更改其语言。更新应用程序和 activity 上下文对我有帮助。以下是 MainActivity 函数的示例:
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());
}
在使用所有来源的所有解决方案后,我终于找到了我的问题。这让我生气了2天。
大家都知道在Android Oreo (API 26) 中我们必须使用createConfigurationContext
,但我的问题是使用带有local 的Country name。
替换
en_US with en
ar_AE with ar
fa_IR 和 fa
我的问题解决了。
希望对某人有所帮助