[英]How to change Android O / Oreo / api 26 app language
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);
对于api> 25,我放了
Locale.setDefault(Locale.Category.DISPLAY, mynewlanglocale);
before setContentView(R.layout.activity_main);
在
setContentView(R.layout.activity_main);
之前setContentView(R.layout.activity_main);
but nothing changes. 但没有变化。
Yes in android Oreo localization is not working fine with updateconfiguration. 是的在android Oreo本地化与updateconfiguration无法正常工作。 But it is deprecated in android N itself.
但它在Android N本身被弃用了。 Instead of updateconfiguration use createconfiguration in each attachcontext.
而不是更新配置使用每个attachcontext中的createconfiguration。 it is working fine for me.
它对我来说很好。 Try this...
试试这个...
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);
}
I had the same problem: since Android 8.0+ some parts of my app did't change their language anymore. 我有同样的问题:因为Android 8.0+我的应用程序的某些部分不再改变他们的语言。 Updating of both application and activity context helps me.
更新应用程序和活动上下文对我有帮助。 Here is an example of MainActivity function:
以下是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());
}
updateConfiguration
is deprecated and you should use createConfigurationContext
. 不推荐使用
updateConfiguration
,您应该使用createConfigurationContext
。 I solved it this way: 我这样解决了:
@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);
}
Updated For All android versions till Oreo 更新了所有Android版本,直到奥利奥
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). 这三个函数应该写在Utiltiy类中(您的首选项)。 Then when you select the app language from the app, call the setSelectedLanguageId() function and pass the language id as parameter.
然后,当您从应用程序中选择应用程序语言时,请调用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. 这里的PreferenceUtil是我的Utiltiy类。 You should replace it with your utility class function.
您应该用实用程序类函数替换它。
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. 请记住,我们将活动的上下文传递给initAppLanguage()函数,而不是应用程序上下文。 Passing the Application context won't make it work in Oreo(atleast for me).
传递应用程序上下文不会使它在奥利奥(至少对我来说)有效。
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); startActivity(ⅰ);
Hope this helps you! 希望这对你有所帮助!
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 Developers article: 我推荐阅读这篇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. 希望能帮助到你。
Here is complete solution worked for kitkat, Lollipop, Marshmallow, Nougat and Oreo too. 这里是kitkat,Lollipop,Marshmallow,Nougat和Oreo的完整解决方案。 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();
}
你需要使用getApplicationContext()
而不是getContext()
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_US with en en_US with en
ar_AE with ar ar_AE with ar
fa_IR with fa fa_IR with fa
And my problem solved. 我的问题解决了。
Hope to help someone 希望能帮助别人
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.