Android6.0和7.0应用层更改系统语言(反射)
来源:互联网 发布:bugclose 源码下载 编辑:程序博客网 时间:2024/06/06 18:27
转载注明出处:
http://blog.csdn.net/zhaokai621/article/details/77102308
当处于应用层时,如果只是修改应用内多语言时,上层app可以轻松完成各种语言的切换,网上方法很多,就不在详细叙述,app内部设置多语言可参考下面这篇文章
Android 实现应用内置语言切换(附有源码下载地址7.0可用)。
但是,如何通过app,设置系统语言呢?这正是本文讨论核心。
android6.0
android设置系统语言的核心方法在framework层,地址是\frameworks\base\core\java\com\android\internal\app\LocalePicker.java类里,方法如下:
/**
* Requests the system to update the system locale. Note that the system looks halted
* for a while during the Locale migration, so the caller need to take care of it.
*/
public static void updateLocale(Locale locale) {
try {
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
config.setLocale(locale);
config.userSetLocale = true;
am.updateConfiguration(config);
// Trigger the dirty bit for the Settings Provider.
BackupManager.dataChanged("com.android.providers.settings");
} catch (RemoteException e) {
// Intentionally left blank
}
}
android6.0设置系统语言的关键逻辑就是上面那个方法。如果上层APP想要设置系统语言必须通过反射方法获取,核心方法代码如下(本方法可以持久化系统语言设置,也就是说重启手机后不会恢复默认系统语言):
private void changeSystemLanguage(Locale locale) { if (locale != null) { try { Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative"); Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault"); Object objIActivityManager = getDefault.invoke(classActivityManagerNative); Class classIActivityManager = Class.forName("android.app.IActivityManager"); Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration"); Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager); config.setLocale(locale); //config.userSetLocale = true; Class clzConfig = Class .forName("android.content.res.Configuration"); java.lang.reflect.Field userSetLocale = clzConfig .getField("userSetLocale"); userSetLocale.set(config, true); Class[] clzParams = {Configuration.class}; Method updateConfiguration = classIActivityManager.getDeclaredMethod("updateConfiguration", clzParams); updateConfiguration.invoke(objIActivityManager, config); BackupManager.dataChanged("com.android.providers.settings"); } catch (Exception e) { Log.d(TAG, "changeSystemLanguage: " + e.getLocalizedMessage()); } }}调用时如下:
Local locale = Locale.ENGLISH;
系统语言就变成了英文。(不再赘述)changeSystemLanguage(locale);
android7.0
7.0与6.0的源码有所不同,LocalePicker.Java定义系统语言的方式,不在是一种Local,而是一个LocaleList,具体方法如下:
public static void updateLocale(Locale locale) {
updateLocales(new LocaleList(locale));
}
updateLocale调用了updateLocales方法,updateLocales方法如下:
public static void updateLocales(LocaleList locales) {
try {
final IActivityManager am = ActivityManagerNative.getDefault();
final Configuration config = am.getConfiguration();
config.setLocales(locales);
config.userSetLocale = true;
am.updatePersistentConfiguration(config);
// Trigger the dirty bit for the Settings Provider.
BackupManager.dataChanged("com.android.providers.settings");
} catch (RemoteException e) {
// Intentionally left blank
}
}
可见,6.0上的反射直接照搬到7.0是不起作用的,需要重新运用反射方法,反射方法代码如下
protected void changeSystemLanguage(LocaleList locale) { if (locale != null) { try { Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative"); Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault"); Object objIActivityManager = getDefault.invoke(classActivityManagerNative); Class classIActivityManager = Class.forName("android.app.IActivityManager"); Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration"); Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager); config.setLocales(locale); Class[] clzParams = {Configuration.class}; Method updateConfiguration = classIActivityManager.getDeclaredMethod("updatePersistentConfiguration", clzParams); updateConfiguration.invoke(objIActivityManager, config); } catch (Exception e) { Log.d(TAG, "changeSystemLanguage: " + e.getLocalizedMessage()); } }}
6.0和7.0设置系统语言源码不同之出,有两点:
1.设置参数的方法不同,6.0是updateConfiguration,7.0是updatePersistentConfiguration,这点需要注意
2.6.0传递的local,而7.0是一个列表LocaleList
7.0反射方法调用如下:
Locale newLocale = new Locale("zh", "CN");final LocaleList localeList = new LocaleList(newLocale);changeSystemLanguage(localeList);
android7.0app切换系统语言Demo源码下载:http://download.csdn.net/download/zhaokai621/9930068
生成的apk,需要系统签名,可放在源码vendor\customer\你的文件下通过mm编译,需要注意的是,需要有.mk文件,生成的apk在out的目录下(当然层级有很多),把out目录下生成的apkpush到手机system/priv-app/你的文件夹,重启手机即可。
操作如下:
1.把studio生成的apk放入如下目录:
Android.mk文件如下(供参考):
--------------------------开始(下面才是)-------------------------------------------------------------
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_OVERRIDES_PACKAGES := Calendar
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := platform
#LOCAL_PREBUILT_JNI_LIBS:= \
#@lib/armeabi/liblocSDK4d.so
#LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_PREBUILT)
--------------------------------结束(本行不是)-----------------------------------------------------------------------------
2.编译源码,单编模块
命令如下(前提是你已经整编过一套android源码)
source ./build/envsetup.sh(加载命令)
lunch 16(序号和你整编时选的一样,本文以android7.0源码为准)
mmm vendor/customer/Test
3.生成的apk(已经打包了系统签名):在如下目录(可能有出入)
4.push到手机,不要install,重启手机
adb push XXXX system/priv-app/Test
XXX是你out生成的apk,可拖拽到此。
现在就可以看到一个应用了,点击就可以切换系统语言了。多多交流 *-*
android7.0app切换系统语言Demo源码下载:http://download.csdn.net/download/zhaokai621/9930068
- Android6.0和7.0应用层更改系统语言(反射)
- Android应用更改系统语言
- Android6.0 如何添加更改系统设置权限
- Android6.0的phone应用源码分析(5)——RIL层分析
- Android6.0的phone应用源码分析(6)——RIL层框架分析
- Android6.0的phone应用源码分析(7)——RIL层框架分析2
- Android6.0的phone应用源码分析(5)——RIL层分析
- Android6.0的phone应用源码分析(7)——RIL层框架分析2
- Android6.0 在framwoard 层系统拦截HOME键
- 源码android6.0 系统应用时钟--详细的闹钟分析
- 嵌入式系统分为4层,硬件层、驱动层、操作系统层和应用层。
- Android6.0 应用调试
- android6.0/7.0打开系统权限
- MTK6580(Android6.0)-Psensor FrameWork 层分析
- Android6.0系统权限
- Android6.0权限系统
- Android6.0系统权限
- Android6.0 属性系统
- Spring Boot Profile 与Maven Profile 集成实践
- jQuery
- 多线程 队列 线程阻塞
- hdu 2602 简单的01背包
- 多校联萌(三) QAQ & 君临天下 || 天行九歌
- Android6.0和7.0应用层更改系统语言(反射)
- [SDUT](3469)深度优先搜索练习之神奇的矩环 ---DFS(图)
- 数据库测试
- webSQL操作数据库
- HDU6098-2017多校6-贪心&水-Inversion
- Servlet下载服务器文件
- tcp+opencv 视频传输
- HDU6105(博弈题,非酋得不到救赎)
- spring cloud