转载请标明出处: http://blog.csdn.net/u011974987/article/details/50801770;
本文出自:【Xiho的博客】

概述:

简单介绍下这个需求的缘由,这段时间因公司业务需要,其中有一项“设置系统语言”功能,就是在使用APP的过程中,动态的去切换整个Android机器的语言,具体参照手机设置页面有语言切换功能。期初想来是很简单的事情嘛,不就是个简单的资源国际化嘛,strings.xml资源文件一整还不给OK?真正动起手来就真不是这么一回事了,国际化是没问题,但是怎样能更改所有页面的文字资源呢,这是一个问题。下面介绍下网上找的几个方案。

一、API欺骗

烧制到手机中的android.jar包含了Android所需的各种类与方法;而供开发者使用的android.jar只是其中的一部分。API欺骗是指在应用中去模拟未公开的类和方法让应用编译通过并生成APK,然而在应用实际运行中调用的却仍是烧制到手机中真实的android.jar。

二、使用Java反射机制

IActivityManager与ActivityManagerNative都是非公开类,使用Java反射去调用其中的方法。

但是这个弊端是显而易见的,上述两种方法都是去更改系统的语言的类型,功能和你去设置页面去设置语言类型的效果一样。发现对当前系统设置了新的Locale后,不单自己的应用语系改变了,系统所有的应用语系都改变了,这正是我们所需要的。折腾了下下这个很2的问题。网上放的方法比较旧, Android5.1的话, 设置后当时生效, 重启后就失效了。

核心代码如下:

/** * TODO<更新系统语言> * * @author Xiho * @versionCode 1 <每次修改提交前+1> */@SuppressWarnings("unchecked")public class LanguageUtils {    public static void updateLanguage(Locale locale) {        try {            Object objIActMag, objActMagNative;            Class clzIActMag = Class.forName("android.app.IActivityManager");            Class clzActMagNative = Class                    .forName("android.app.ActivityManagerNative");            //amn = ActivityManagerNative.getDefault();             Method mtdActMagNative$getDefault = clzActMagNative                    .getDeclaredMethod("getDefault");            objIActMag = mtdActMagNative$getDefault.invoke(clzActMagNative);             // objIActMag = amn.getConfiguration();             Method mtdIActMag$getConfiguration = clzIActMag                    .getDeclaredMethod("getConfiguration");            Configuration config = (Configuration) mtdIActMag$getConfiguration                    .invoke(objIActMag);            // set the locale to the new value             config.locale = locale;            //持久化 config.userSetLocale = true;             Class clzConfig = Class                    .forName("android.content.res.Configuration");            java.lang.reflect.Field userSetLocale = clzConfig                    .getField("userSetLocale");            userSetLocale.set(config, true);            // 此处需要声明权限:android.permission.CHANGE_CONFIGURATION            // 会重新调用 onCreate();            Class[] clzParams = { Configuration.class };            // objIActMag.updateConfiguration(config);            Method mtdIActMag$updateConfiguration = clzIActMag                    .getDeclaredMethod("updateConfiguration", clzParams);            mtdIActMag$updateConfiguration.invoke(objIActMag, config);            BackupManager.dataChanged("com.android.providers.settings");        } catch (Exception e) {            e.printStackTrace();        }    }}

这样我们利用JAVA的反射机制,调用那些隐藏的方法就可以实现了。

  • 需要注意的是调用此方法:
// objIActMag.updateConfiguration(config);mtdIActMag$updateConfiguration.invoke(objIActMag, config);

需要加上权限:

android.permission.CHANGE_CONFIGURATION

并且此处会重新调用onCreate方法,我就在这个地方处被坑了一把。(如果调用此方法的时候做了一些逻辑,就注意下)。

不同的地方在添加了

Class clzConfig = Class.forName("android.content.res.Configuration"); java.lang.reflect.Field userSetLocale = clzConfig.getField("userSetLocale"); userSetLocale.set(config, true);

Debug发现的逻辑是:
1: 持久化保存下来

SystemProperties.set("persist.sys.language", l.getLanguage());SystemProperties.set("persist.sys.country", l.getCountry());

2: 开机AndroidRuntime读取这个属性, 更新系统之前的属性。估计是为了方便跑测试的Case添加的这个逻辑。

最后声明:

既然是更改系统的配置当然你的签名也应该是系统签名和sharedUserId。不然会类似以下的错误!

error:

java.lang.SecurityException: Permission Denial: updateConfiguration() from pid=31594, uid=10099 requires android.permission.CHANGE_CONFIGURATION

各位都注意下吧~

附上GitHub源码:SwitchLanguage;

welcome everyone’s Star and fork!

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. android上一些方法的区别和用法的注意事项
  5. android实现字体闪烁动画的方法
  6. Android(安卓)Wifi模块分析(三)
  7. Android中dispatchDraw分析
  8. Android四大基本组件介绍与生命周期
  9. Android(安卓)MediaPlayer 常用方法介绍

随机推荐

  1. TextView英文自动换行解决方法
  2. android时区的初始化
  3. android如何设置全屏模式
  4. EditText属性大全
  5. Android(安卓)中的消息传递,详解广播机制
  6. [Android系列—] 1. Android(安卓)开发环
  7. Android中TextView 行间距和段间距设置
  8. Android(安卓)studio 串口通信(动态获取
  9. Android(安卓)Design Support Library—
  10. 学习Android(安卓)必备 实例大集合