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時,切換語言的功能不要去執行!