android13(T) 客制化预置语言列表

效果图

android13(T) 客制化预置语言列表_第1张图片

需求分析

这个列表界面一般都是后来手动添加后才现实的,通过分析源码发现通过如下值可控

adb shell settings get system system_locales

zh-CN,ja-JP,en-AT

所以只需查询出这个值,然后加在 SettingProvider 中即可

隐藏 bug

如果客户要求默认语言为 en-AT,且客制列表顺序如上显示,通过之前惯用设置语言反射接口设置后,

有bug版本接口 使用 updateConfiguration

 public void changeSystemLanguage(Locale locale) {//Locale.ENGLISH
        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 getConfiguration = clzIActMag.getDeclaredMethod("getConfiguration");

            Configuration config = (Configuration) getConfiguration.invoke(objIActMag);
            config.locale = locale;

            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 mtdIActMag$updateConfiguration = clzIActMag.getDeclaredMethod("updateConfiguration", clzParams);
            mtdIActMag$updateConfiguration.invoke(objIActMag, config);
            BackupManager.dataChanged("com.android.providers.settings");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

首次开机预置语言列表将不显示,重启一次后才会正确显示。经过分析是设置语言接口的锅,

替换新方法即可解决

正常版本接口 使用 updatePersistentConfiguration

private LocaleList makeLocalListData(Context mContext, String locale) {
//        String defaultConfig = "zh-CN,ja-JP,en-AT";
        String defaultConfig = Settings.System.getString(mContext.getContentResolver(),"system_locales");
        String[] split = defaultConfig.split(",");
        int index=0;
        String newConfig = "";
        for (int i = 0; i < split.length; i++) {
            if (split[i].contains(locale)) {
                index = i;
                newConfig = split[i];
                break;
            }
        }

        for (int i = 0; i < split.length; i++) {
            if (i == index) {
                continue;
            }
            newConfig = newConfig.concat(","+split[i]);
        }

        return LocaleList.forLanguageTags(newConfig);
    }

    public void changeSystemLocales(Context mContext, String locale) {
        try {
            LocaleList localeList = makeLocalListData(mContext, locale);
            Class iActivityManager = Class.forName("android.app.IActivityManager");
            Class activityManagerNative = Class.forName("android.app.ActivityManagerNative");
            Method getDefault = activityManagerNative.getDeclaredMethod("getDefault");
            Object objIActMag = getDefault.invoke(activityManagerNative);
            Method getConfiguration = iActivityManager.getDeclaredMethod("getConfiguration");
            Configuration config = (Configuration) getConfiguration.invoke(objIActMag);
            config.setLocales(localeList);
            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 = iActivityManager.getDeclaredMethod("updatePersistentConfiguration", clzParams);
            updateConfiguration.invoke(objIActMag, config);
            BackupManager.dataChanged("com.android.providers.settings");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

你可能感兴趣的:(Android12-13,源码修改,预置语言)