网络上的方法,应用反射的方法进行系统设置
权限,需要修改系统配置文件的权限,需要系统权限
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
tools:ignore="ProtectedPermissions" />
private void setLanguage(Locale setLocaleLanguage) {
Log.d("zwt","设置语言");
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(setLocaleLanguage);
Class clzConfig = Class.forName("android.content.res.Configuration");
Field userSetLocale = clzConfig.getField("userSetLocale");
userSetLocale.set(config, true);
Class[] clzParams = new Class[]{Configuration.class};
Method updateConfiguration = classIActivityManager.getDeclaredMethod("updateConfiguration", clzParams);
updateConfiguration.invoke(objIActivityManager, config);
BackupManager.dataChanged("com.android.providers.settings");
} catch (Exception var12) {
Log.d("zwt", "setLanguage: " + var12.getLocalizedMessage());
}
}
调用
setLanguage(Locale.ENGLISH);//英语
//Locale 类中有些语言没有,可以用下面的方法进行设置,只要系统支持这种语言就能设置成功
Locale portuguese = new Locale("pt");
setLanguage(portuguese); //葡萄牙语
上面是用的反射的方法,发现在原生的设置里面有些功能会闪退,例如切换语言后,设置时区设置会闪退,跟踪log发现是下面的local.getCountry(); 获得国家的方法获得为空,导致zoneIds 这个List 获得为空,爆出空指针的错误

解决办法,发现系统中有封装好的修改语言的方法,不过是对非系统应用隐藏了,com.android.internal.app.LocalePicker 这个类对非系统用户隐藏了
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import com.android.internal.app.LocalePicker;
private final Map<String, LocalePicker.LocaleInfo> mLocaleInfoMap = new HashMap<String, LocalePicker.LocaleInfo>();
private Locale mNewLocale;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获得系统支持的所有语言信息
final List<LocalePicker.LocaleInfo> localeInfoList = LocalePicker.getAllAssetLocales(SystemActivity.this, false);
for (final LocalePicker.LocaleInfo localeInfo : localeInfoList) {
final String languageTag = localeInfo.getLocale().toLanguageTag();
mLocaleInfoMap.put(languageTag, localeInfo);
Log.d("zwt", "::::"+languageTag);
}
}
// 设置系统默认语言
private void setLanguage(String languageTag) {
mNewLocale = mLocaleInfoMap.get(languageTag).getLocale();
mDelayHandler.removeCallbacks(mSetLanguageRunnable);
mDelayHandler.postDelayed(mSetLanguageRunnable, 500);
}
private final Handler mDelayHandler = new Handler();
private final Runnable mSetLanguageRunnable = new Runnable() {
@Override
public void run() {
LocalePicker.updateLocale(mNewLocale);
}
};
最主要的是 LocalePicker.updateLocale(mNewLocale); 去设置系统的配置文件,修改系统语言
调用
//设置简体中文
setLanguage("zh-CN");
至于传入的字符串的值,可以看上面 onCreate 中的 languageTag log打印
最后成功解决