• Android 根据SIM卡自动切换语言


    1. 实现只在Google setup wizard情况下才切换SIM卡语言,其余时候(比如已经开机进入Home)不切换语言

    在/frameworks/opt/telephony/src/java/com/android/internal/telephony/MccTable.java中添加:

    public static void updateMccMncConfiguration(Context context, String mccmnc) {
           ...
                Slog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
                Locale mccLocale = null;
                if (mcc != 0) {
                    setTimezoneFromMccIfNeeded(context, mcc);
                    mccLocale = getLocaleFromMcc(context, mcc,null);//添加这句读取SIM语言
                }
    
                try {
                    Configuration config = new Configuration();
                    boolean updateConfig = false;
                    if (mcc != 0) {
                        config.mcc = mcc;
                        config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc;
                        updateConfig = true;
                    }
    
                   //Add code BEGIN
                    if(UPDATE_SIM_LANGUAGE) {
                        boolean isDeviceProvisioned = Settings.Global.getInt(
                                context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,0) != 0;
                        boolean setupCompleted = Settings.Secure.getInt(context.getContentResolver(),
                                Settings.Secure.USER_SETUP_COMPLETE,0) != 0;
    
                        if (mccLocale != null && !isDeviceProvisioned && !setupCompleted) {
                            Configuration sysConfig = new Configuration();
                            sysConfig = ActivityManager.getService().getConfiguration();;
                            LocaleList currentLocales = sysConfig.getLocales();
                            LocaleList newUserLocales = new LocaleList(mccLocale, currentLocales);
                            config.setLocales(newUserLocales);
                            updateConfig = true;
                            Settings.System.putConfiguration(context.getContentResolver(), config);
                        }
                    }
                   //Add code END
    
                    if (updateConfig) {
                        Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config);
                        ActivityManager.getService().updateConfiguration(config);
                    } else {
                        Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
                    }
                } catch (RemoteException e) {
                    Slog.e(LOG_TAG, "Can't update configuration", e);
                }
            }
        }

    此处有下面几个关键点。

    Settings.Global.DEVICE_PROVISIONED 和 Settings.Secure.USER_SETUP_COMPLETE用来判断当前Google SetupWizard有没有结束。

    如果还在SetupWizard画面,这两个值都是0;当SetupWizard结束,这两个会被设定为1.

    ActivityManager.getService().updateConfiguration(config) 会呼叫到ActivityTaskManagerService里面,但真正走到update config之前,会有下面的code

    if (values != null) {
        Settings.System.clearConfiguration(values);
    }

    也就是会把通过Configuration设定进来的Locale设定清除(不清楚为什么这么设定)

            /**
             * @hide Erase the fields in the Configuration that should be applied
             * by the settings.
             */
            public static void clearConfiguration(Configuration inoutConfig) {
                inoutConfig.fontScale = 0;
                if (!inoutConfig.userSetLocale && !inoutConfig.getLocales().isEmpty()) {
                    inoutConfig.clearLocales();
                }
            }

    因此,还需要再在frameworks/base/services/core/java/com/android/server/am/ActivityTaskManagerService.java中添加:

    @Override
        public boolean updateConfiguration(Configuration values) {
            mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
    
            ...
    
                final long origId = Binder.clearCallingIdentity();
                try {
                    //Add code BEGIN
                    if(UPDATE_SIM_LANGUAGE){
                        boolean isDeviceProvisioned = Settings.Global.getInt(
                                mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
                        boolean setupCompleted = Settings.Secure.getInt(mContext.getContentResolver(),
                                Settings.Secure.USER_SETUP_COMPLETE,0) != 0;
    
                        if(isDeviceProvisioned || setupCompleted){
                            if (values != null) {
                                Settings.System.clearConfiguration(values);
                            }
                        }
                    }else { //保留原有
                        if (values != null) {
                            Settings.System.clearConfiguration(values);
                        }
                    }
                    //Add code END
                    updateConfigurationLocked(values, null, false, false /* persistent */,
                            UserHandle.USER_NULL, false /* deferResume */,
                            mTmpUpdateConfigurationResult);
                    return mTmpUpdateConfigurationResult.changes != 0;
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
            }
        }

    2. 如果想每次插入SIM卡都要切换成SIM卡语言,只需要把第一步里面关于isDeviceProvisioned和setupCompleted的判断拿掉就行,也就是每次插入SIM卡都会默认切换成SIM卡语言。

    3. 如果只想SIM卡插入第一次才去切换,先把第一步的isDeviceProvisioned和setupCompleted的判断拿掉,再去判断Settings.System.SYSTEM_LOCALES是否已经包含当前SIM卡语言。

    判断时候不要用mccLocale.toString(),会有zh-CN和zh_CN的差异,用mccLocale.getLanguage(),只去判断zh就好

    WARNING:报BUG啦!

    按照方法1修改代码后,功能可以实现,但是在Settings中设置startup security(开机启动需要解锁)的话,在开机到secure startup画面时,所有user setting不能被访问。

    因此此时 Settings.Global.DEVICE_PROVISIONED 和Settings.Secure.USER_SETUP_COMPLETE读出来都是默认值!

    因此需要再在Settings中CryptKeeper.java中去添加一个flag,activity start时候flag设为true,onDestroy时候清除flag。

    这时在方法1添加判断的地方添加一个读Settings字段flag的功能,发现此时是secure startup时,切换语言的功能不要去执行!

  • 相关阅读:
    Odoo中的Widget
    Odoo中的domain
    Odoo中的模型详解
    Odoo中的模型继承、视图继承、Qweb模板继承详解
    Odoo权限控制详解
    Odoo字段类型详解
    WSGI——python web 服务器网关接口
    Backbone——数据驱动UI的js开发模式
    Underscore——JS函数库
    Werkzeug——python web开发工具包
  • 原文地址:https://www.cnblogs.com/kunkka/p/12937251.html
Copyright © 2020-2023  润新知