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地址

MultiLanguagesSwitch

转自: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内切换语言不生效的问题的更多相关文章

  1. App内切换语言

    前几天客户提需求,对App增加一个功能,这个功能目前市面上已经很常见,那就是应用内切换语言.啥意思,就是 英.中.法.德.日...语言随意切换. (本案例采用Data-Bingding模式,麻麻再也不 ...

  2. IOS APP 国际化 程序内切换语言实现 不重新启动系统(支持项目中stroyboard 、xib 混用。完美解决方案)

    上篇 IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源 介绍了纯代码刷新 实现程序内切换语言. 但效率底下,也存在一些问题.暂放弃. ...

  3. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  4. 我的Android进阶之旅------>如何解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->如何解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  5. 我的Android进阶之旅------&gt;怎样解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  6. Android 应用内切换语言

    extends :http://bbs.51cto.com/thread-1075165-1.html,http://www.cnblogs.com/loulijun/p/3164746.html 1 ...

  7. iOS APP语言国际化之应用内切换语言环境

    最近接了一个项目,需求是要做一款应用的英文版本,客户并不清楚,以为要另做一个APP.沟通后告诉他们在之前应用基础上加个国际化功能就好,把之前的语言国际化重新梳理记录一下. 一般设置更改本地语言环境后, ...

  8. 另辟思路解决 Android 4.0.4 不能监听Home键的问题

    问题描述: 自从Android 4.0以后,开发人员是不能监听和屏蔽Home键的,对于KEYCODE_HOME,官方给出的描述如下: Home key. This key is handled by ...

  9. 如何解决Android 5.0中出现的警告:Service Intent must be explicit

    有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent  must be explitict,也就是说从Lollip ...

随机推荐

  1. Android adb 命令速查表

    常用命令 devices # 查看已连接的设备 start-server # 启动 adb server kill-server # 停止 adb server logcat # 查看日志 insta ...

  2. [svc]centos6上部署openvpn+gg二步认证

    最近又发现个新的vpn: wireguard 为了满足员工在家办公的需求.需要 openvpn+gg方案 在centos6上部署openvpn 参考 1.安装前准备 wget -O /etc/yum. ...

  3. Robolectric使用教程

    转载请标明出处:http://blog.csdn.net/shensky711/article/details/53561172 本文出自: [HansChen的博客] 概述 怎样使用 为项目加入依赖 ...

  4. HTML5学习笔记(二十一):BOM

    BOM(Browser Object Model) 是指浏览器对象模型. 由于最初JavaScript就是设计在浏览器中执行的脚本语言,所以BOM是浏览器提供给JavaScript操作自身的接口. w ...

  5. Linux 守护进程

    1.什么是守护进程 守护进程daemon指的是在后台运行的进程 2.前台任务和后台任务 前台任务:独占命令行窗口,运行完毕或手动终止,才能执行其他命令 以redis服务为例 redis-server ...

  6. MyBatis 问题列表

    问题表现:The content of elements must consist of well-formed character data or markup 解决办法:1.配置的动态SQL语句里 ...

  7. Upgrade Bash to 4+ on OS X

    http://buddylindsey.com/upgrade-bash-to-4-on-os-x/ Unfortunately, Apple has decided to ship an old v ...

  8. 【MLP】多层感知机网络

    BPN(Back Propagation Net) 反向传播神经网络是对非线性可微分函数进行权值训练的多层网络,是前向神经网络的一种. BP网络主要用于: 1)函数逼近与预测分析:用输入矢量和相应的输 ...

  9. sed行处理详解(交换行,合并行,删除行等)

    1.合并行 zj@zj:~/Script/blog_script$ cat test11234合并上下两行zj@zj:~/Script/blog_script$ sed '$!N;s/\n/\t/' ...

  10. shell 删除文件过期文件

    删除创建时间大于30天的文件 find /archivelog -ctime + | xargs rm -rf -amin n #查找系统中最后N分钟访问的文件 -atime n #查找系统中最后n* ...