java 如何更改 Android O / Oreo / api 26 应用程序语言
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47165311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change Android O / Oreo / api 26 app language
提问by Marius Razvan Varvarei
I want to change the language of the app and this works fine until API 26.
我想更改应用程序的语言,这在 API 26 之前都可以正常工作。
For api > 25 I put Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
before setContentView(R.layout.activity_main);
but nothing changes.
对于 api > 25 我Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
之前放过setContentView(R.layout.activity_main);
但没有任何变化。
The docsdon't explain too much about this.
该文档不解释太多关于这一点。
回答by Skeptiker
I had the same problem: since Android 8.0+ some parts of my app did't change their language anymore. Updating of both application and activity context helps me. Here is an example of MainActivity function:
我遇到了同样的问题:自从 Android 8.0+ 以来,我的应用程序的某些部分不再更改它们的语言。应用程序和活动上下文的更新对我有帮助。这是 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());
}
回答by Rajalakshmi Arumugam
Yes in android Oreo localization is not working fine with updateconfiguration. But it is deprecated in android N itself. Instead of updateconfiguration use createconfiguration in each attachcontext. it is working fine for me. Try this...
是的,在 android Oreo 中,本地化在使用更新配置时无法正常工作。但它在 android N 本身中已被弃用。在每个 attachcontext 中使用 createconfiguration 代替 updateconfiguration。它对我来说很好用。试试这个...
In you activity add this..
在你的活动中添加这个..
@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);
}
}
In MyContextWrapper.java
在 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);
}
回答by Luke
updateConfiguration
is deprecated and you should use createConfigurationContext
. I solved it this way:
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);
}
回答by emilpmp
Updated For All android versions till Oreo
更新所有安卓版本,直到奥利奥
Create a class like this
创建一个这样的类
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;
}
}
}
Now when you select the language from your app, Save the language code in Shared Preference like below
现在,当您从应用程序中选择语言时,将语言代码保存在共享首选项中,如下所示
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");
}
These three functions should be written inside a Utiltiy class(your preference). Then when you select the app language from the app, call the setSelectedLanguageId() function and pass the language id as parameter.
这三个函数应该写在一个 Utiltiy 类中(你的偏好)。然后当您从应用程序中选择应用程序语言时,调用 setSelectedLanguageId() 函数并将语言 ID 作为参数传递。
This way you have saved the selected language in your app. Now in your application class write a function like this
这样你就在你的应用程序中保存了所选的语言。现在在您的应用程序类中编写这样的函数
public void initAppLanguage(Context context){
LocaleUtils.initialize(context, PreferenceUtil.getSelectedLanguageId() );
}
Here the PreferenceUtil is my Utiltiy class. You should replace it with your utility class function.
这里的 PreferenceUtil 是我的 Utiltiy 类。您应该用您的实用程序类函数替换它。
You should also create a variable in your application class
您还应该在应用程序类中创建一个变量
private static Application applicationInstance;
and in your Application class's onCreate method, initialise applicationInstance to be the applications context like this
并在您的 Application 类的 onCreate 方法中,将 applicationInstance 初始化为这样的应用程序上下文
applicationInstance = this;
Now write a getter function in your application class
现在在您的应用程序类中编写一个 getter 函数
public static synchronized Application getInstance() {
return applicationInstance;
}
And now when you start your first activity, call this method in your activity's onCreate
现在当你开始你的第一个活动时,在你的活动的 onCreate 中调用这个方法
Application.getInstance().initAppLanguage(this);
Remember that we are passing the activity's context to the initAppLanguage() function, not the application context. Passing the Application context won't make it work in Oreo(atleast for me).
请记住,我们将活动的上下文传递给 initAppLanguage() 函数,而不是应用程序上下文。传递应用程序上下文不会让它在奥利奥中工作(至少对我来说)。
So when you select the language try to restart your application completely. You can acheive this by
因此,当您选择语言时,请尝试完全重新启动您的应用程序。你可以通过
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
startActivity(i);
开始活动(i);
Hope this helps you!
希望这对你有帮助!
回答by Andre Breton
It is possible, however i would not recommend to set the language programatically
这是可能的,但是我不建议以编程方式设置语言
Android is designed so the System UI and your App have the same language, if you change it programmatically you would be fighting the system
Android 的设计使系统 UI 和您的应用程序具有相同的语言,如果您以编程方式更改它,您将与系统作斗争
Instead what you can do is enable multilanguage support by adding different strings.xml languages, this will change the language automatically
相反,您可以做的是通过添加不同的 strings.xml 语言来启用多语言支持,这将自动更改语言
I reccommend reading through this Google Developersarticle:
我建议通读这篇Google Developers文章:
Supporting Different Languages and Cultures
If you really need to change it programatically you can do the following
如果您确实需要以编程方式更改它,您可以执行以下操作
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());
On SDK >= 21, you need to call 'Resources.updateConfiguration()', otherwise resources will not be updated.
SDK >= 21 需要调用'Resources.updateConfiguration()',否则资源不会更新。
Hope it helps.
希望能帮助到你。
回答by Ness Tyagi
Here is complete solution worked for kitkat, Lollipop, Marshmallow, Nougat and Oreo too. Just follow all below step.
这是适用于奇巧、棒棒糖、棉花糖、牛轧糖和奥利奥的完整解决方案。只需按照以下步骤操作即可。
First create a java class like below
首先创建一个如下所示的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());
}
}
Now add this snippet on Button click where you want to change locale
现在在按钮单击要更改区域设置的位置添加此代码段
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);
Finally paste the below code in Splash Activity or in Launching Activity.
最后将以下代码粘贴到 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();
}
回答by MT Michael Michael Mao
You need to use getApplicationContext()
instead of getContext()
你需要使用getApplicationContext()
而不是getContext()
回答by Radesh
After use all solution in all sources finally i found my issue. That makes me angry for 2 days.
在所有来源中使用所有解决方案后,我终于找到了我的问题。这让我生气了2天。
Everyone knows that in Android Oreo (API 26) we must use createConfigurationContext
, But My problem is using Country name with local.
每个人都知道在 Android Oreo (API 26) 中我们必须使用createConfigurationContext
,但我的问题是在本地使用国家/地区名称。
Replace
代替
en_USwithen
en_US与en
ar_AEwithar
ar_AE与ar
fa_IRwithfa
fa_IR与fa
And my problem solved.
我的问题解决了。
Hope to help someone
希望能帮助某人