android13(T) customized preset language list

renderings

demand analysis

This list interface is usually realized after being manually added later. By analyzing the source code, it is found that it can be controlled by the following values.

adb shell settings get system system_locales

zh-CN,ja-JP,en-AT

So just query this value and add it to SettingProvider

hide bugs

If the customer requires that the default language is en-AT, and the order of the customized list is shown above, after setting it through the previously used language reflection interface,

There is a bug version interface Use 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();
        }
    }

The preset language list will not be displayed at first startup and will be displayed correctly after a restart. After analysis, it is the fault of setting the language interface.

It can be solved by replacing it with a new method

Normal version interface Use 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();
        }
    }

Guess you like

Origin blog.csdn.net/u012932409/article/details/134667759