系统设置 设置中英文切换
方式一:直接调用系统类和方法
1,查看com.android.setting源码中,对中英文切换的大概流程,可以总结为:
try {
//tw add
IActivityManager iActivityManager = ActivityManagerNative.getDefault();
Configuration configuration = iActivityManager.getConfiguration();
configuration.locale = locale;
configuration.userSetLocale = true;
iActivityManager.updateConfiguration(configuration);
//提交到系统数据存储,需要在应用声明,不需要
//BackupManager.dataChanged("com.android.providers.settings");
}catch (Exception e){
XLog.i("updateLocale fail!.....", e);
}
这些类和方法都是只有系统应用才能访问,在标准sdk中是无法访问到的。可以通过系统提供的jar包 framework-base_2.jar
为了AndroidStudio能够编译并找到这些类,gradle中加入这些配置:
allprojects {
repositories {
jcenter()
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:userlib/framework-base_2.jar')
}
}
}
然后加入作为外部引用的jar包:
dependencies {
provided files('../userlib/framework-base_2.jar')
}
但是为了在编译过程中能够通过,并且优先选择系统里面的class文件,需要 app.iml 中找到
<orderEntry type="library" exported="" name="framework-base_2" level="project" />
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
将系统更jar放到 Android API前面,调用系统jar的有点在于方便,前提是,jar包中提供的类和方法必须在你机器系统中能够找到。
方法二:通过反射设置中英文切换
反射调用的流程大致与上面相同,只不过写起来和看起来复杂一点:
try {
Object objIActMag, objActMagNative;
Class clzIActMag = Class.forName("android.app.IActivityManager");
Class clzActMagNative = Class.forName("android.app.ActivityManagerNative");
Method mtdActMagNative$getDefault = clzActMagNative.getDeclaredMethod("getDefault");
objIActMag = mtdActMagNative$getDefault.invoke(clzActMagNative);
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 };
Method mtdIActMag$updateConfiguration = clzIActMag
.getDeclaredMethod("updateConfiguration", clzParams);
mtdIActMag$updateConfiguration.invoke(objIActMag, config);
BackupManager.dataChanged("com.android.providers.settings");
} catch (Exception e) {
XLog.e("updateLocale fail!", e);
}
以上是基于代码实现的设置中英文切换,实际操作过程中遇到,系统设置设置完中英文后,按主页键进入launcher,launcher一直无响应,网上分析的原因是,设置中英文以后,会导致launcher 执行 onstop -> ondestroy ,然后重新 oncreate 然后,按主页键时,从后台切到前台,launcher很长一段时间无响应。
解决方法,需要在清单文件对Activity设置 configChanges 属性,然后再Activity 中重新在onConfigurationChanged中重写更新ui
<activity
android:name="com.inspur.livetv.weblauncher.Main"
android:configChanges="layoutDirection|locale"
android:clearTaskOnLaunch="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="nosensor" >
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
XLog.d("[Main.onConfigurationChanged] !");
updateTextUI();
}
至此,中英文问题已经解决。