解决Android 7.0 App内切换语言不生效的问题
Android7.0及以前版本,Configuration中的语言相当于是App的全局设置:
public static void changeAppLanguage(Context context, String newLanguage){
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
// app locale
Locale locale = getLocaleByLanguage(newLanguage);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(locale);
} else {
configuration.locale = locale;
}
// updateConfiguration
DisplayMetrics dm = resources.getDisplayMetrics();
resources.updateConfiguration(configuration, dm);
}
然后在继承application的类中调用即可:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
onLanguageChange();
}
/**
* Handling Configuration Changes
* @param newConfig newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onLanguageChange();
}
private void onLanguageChange() {
String language;//读取App配置
AppLanguageUtils.changeAppLanguage(this, language);
}
}
Android7.0及之后版本,使用了LocaleList,Configuration中的语言设置可能获取的不同,而是生效于各自的Context。
这会导致:Android7.0使用就的方式,有些Activity可能会显示为手机的系统语言。
Android7.0 优化了对多语言的支持,废弃了updateConfiguration()方法,替代方法:createConfigurationContext(), 而返回的是Context。
也就是语言需要植入到Context中,每个Context都植入一遍。
GitHub地址
转自:https://yanlu.me/android-7-0-app-language-switch/
我自己的使用方式如下:
1.创建工具类
public class AppLanguageUtils {
public static HashMap<String, Locale> mAllLanguages = new HashMap<String, Locale>() {{
put(Constants.ENGLISH, Locale.ENGLISH);
put(Constants.CHINESE, Locale.SIMPLIFIED_CHINESE);
put(Constants.SIMPLIFIED_CHINESE, Locale.SIMPLIFIED_CHINESE);
put(Constants.TRADITIONAL_CHINESE, Locale.TRADITIONAL_CHINESE);
put(Constants.FRANCE, Locale.FRANCE);
put(Constants.GERMAN, Locale.GERMANY);
put(Constants.HINDI, new Locale(Constants.HINDI, "IN"));
put(Constants.ITALIAN, Locale.ITALY);
}};
@SuppressWarnings("deprecation")
public static void changeAppLanguage(Context context, String newLanguage) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
// app locale
Locale locale = getLocaleByLanguage(newLanguage);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLocale(locale);
} else {
configuration.locale = locale;
}
// updateConfiguration
DisplayMetrics dm = resources.getDisplayMetrics();
resources.updateConfiguration(configuration, dm);
}
private static boolean isSupportLanguage(String language) {
return mAllLanguages.containsKey(language);
}
public static String getSupportLanguage(String language) {
if (isSupportLanguage(language)) {
return language;
}
if (null == language) {//为空则表示首次安装或未选择过语言,获取系统默认语言
Locale locale = Locale.getDefault();
for (String key : mAllLanguages.keySet()) {
if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
return locale.getLanguage();
}
}
}
return Constants.ENGLISH;
}
/**
* 获取指定语言的locale信息,如果指定语言不存在{@link #mAllLanguages},返回本机语言,如果本机语言不是语言集合中的一种{@link #mAllLanguages},返回英语
*
* @param language language
* @return
*/
public static Locale getLocaleByLanguage(String language) {
if (isSupportLanguage(language)) {
return mAllLanguages.get(language);
} else {
Locale locale = Locale.getDefault();
for (String key : mAllLanguages.keySet()) {
if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
return locale;
}
}
}
return Locale.ENGLISH;
}
public static Context attachBaseContext(Context context, String language) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
} else {
return context;
}
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Resources resources = context.getResources();
Locale locale = AppLanguageUtils.getLocaleByLanguage(language);
Configuration configuration = resources.getConfiguration();
configuration.setLocale(locale);
configuration.setLocales(new LocaleList(locale));
return context.createConfigurationContext(configuration);
}
}
2.在继承application的类中重写attachBaseContext()方法等操作
private static Context sContext;
private String language; @Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(AppLanguageUtils.attachBaseContext(base, getAppLanguage(base)));
} @Override
public void onCreate() {
super.onCreate();
sContext = this;
spu = new SharedPreferencesUtil(getApplicationContext());
language = spu.getString("language");
onLanguageChange();
} public static Context getContext() {
return sContext;
} /**
* Handling Configuration Changes
* @param newConfig newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onLanguageChange();
} private void onLanguageChange() {
// AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(getAppLanguage(this)));
AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(language));
} private String getAppLanguage(Context context) {
String appLang = PreferenceManager.getDefaultSharedPreferences(context)
.getString("language", Constants.ENGLISH);
return appLang ;
}
3.在需要切换语言的SetLanguageActivity中设置切换方法
private void onChangeAppLanguage(String newLanguage) {
spu.putString("language", newLanguage);
AppLanguageUtils.changeAppLanguage(this, newLanguage);
AppLanguageUtils.changeAppLanguage(App.getContext(), newLanguage);
this.recreate();
}
4.跳转到SetLanguageActivity的原界面语言需要刷新
//携参跳转
startActivityForResult(new Intent(OriginActivity.this, SetLanguageActivity.class), CHANGE_LANGUAGE_REQUEST_CODE);
//切换后返回刷新
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHANGE_LANGUAGE_REQUEST_CODE) {
recreate();
}
}
That's all.
解决Android 7.0 App内切换语言不生效的问题的更多相关文章
- App内切换语言
前几天客户提需求,对App增加一个功能,这个功能目前市面上已经很常见,那就是应用内切换语言.啥意思,就是 英.中.法.德.日...语言随意切换. (本案例采用Data-Bingding模式,麻麻再也不 ...
- IOS APP 国际化 程序内切换语言实现 不重新启动系统(支持项目中stroyboard 、xib 混用。完美解决方案)
上篇 IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源 介绍了纯代码刷新 实现程序内切换语言. 但效率底下,也存在一些问题.暂放弃. ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:
我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...
- 我的Android进阶之旅------>怎样解决Android 5.0中出现的警告: Service Intent must be explicit:
我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...
- Android 应用内切换语言
extends :http://bbs.51cto.com/thread-1075165-1.html,http://www.cnblogs.com/loulijun/p/3164746.html 1 ...
- iOS APP语言国际化之应用内切换语言环境
最近接了一个项目,需求是要做一款应用的英文版本,客户并不清楚,以为要另做一个APP.沟通后告诉他们在之前应用基础上加个国际化功能就好,把之前的语言国际化重新梳理记录一下. 一般设置更改本地语言环境后, ...
- 另辟思路解决 Android 4.0.4 不能监听Home键的问题
问题描述: 自从Android 4.0以后,开发人员是不能监听和屏蔽Home键的,对于KEYCODE_HOME,官方给出的描述如下: Home key. This key is handled by ...
- 如何解决Android 5.0中出现的警告:Service Intent must be explicit
有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent must be explitict,也就是说从Lollip ...
随机推荐
- SonarQube学习入门指南
1. 什么是SonarQube? SonarQube 官网:https://www.sonarqube.org/ SonarQube®是一种自动代码审查工具,用于检测代码中的错误,漏洞和代码异味.它可 ...
- IOS 设备备份文件详解 (二)
这篇主要讲解如何解析Manifest.mbdb文件. 使用二进制工具打开这个文件,文件的头6个字节是固定的,相当于是文件的一种标识 后面的内容是一个一个的项,可以使用一个循环来读取文件,一个一个解析. ...
- [100]tar命令打包(排除目录或文件)
在linux中可以用tar打包目录以方便传输or备份,我们先来看一个例子 Linux下tar命令exclude选项排除指定文件或目录 test 文件夹有如下文件 [root@lee ~]# ll te ...
- 常用的NodeJS模块
图片处理 1.Manipulate images 官网:http://github.com/aheckmann/gm ImageMagick和GraphicsMagick主要用于图片的创建.编辑.合成 ...
- android笔记---主界面(一)
<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="htt ...
- (原创)用c++11实现简洁的ScopeGuard
ScopeGuard的作用是确保资源面对异常时总能被成功释放,就算没有正常返回.惯用法让我们在构造函数里获取资源,当因为异常或者正常作用域结束,那么在析构函数里释放资源.总是能释放资源.如果没有异常抛 ...
- 每日英语:A Buying Guide to Air-Pollution Masks
Blue skies were finally visible in the capital on Thursday after the region suffered fromseven strai ...
- 李洪强iOS经典面试题
李洪强iOS经典面试题 1. struct和class的区别 swift中,class是引用类型,struct是值类型.值类型在传递和赋值时将进行复制,而引用类型则只会使用引用对象的一个"指 ...
- VS2015打开项目慢、死机和卡顿解决方案
VS2015功能强大,但是经常慢 网上有解决方案如下几个,留着备用: 1.选项-环境-基于客户端性能自动调整视觉体验,去掉选项. 2.选项-源代码管理-插件选无. 3.选项-文本编辑器-所有语言-滚动 ...
- Java运行时动态加载类之ClassLoader
https://blog.csdn.net/fjssharpsword/article/details/64922083 *************************************** ...