需求
要求系统语言跟随SIM卡的语言变化。
语言设定
(1)系统预置语言, 即在makefile中指定的语言
(2)重启, 如果未插卡, 则系统语言为预置的语言
(3)重启插入SIM卡开机, 会自适应为SIM卡的语言
(4)如果有手动设置语言, 以后开机, 不管插入的是哪个国家的卡, 都会显示设置的语言, 不会根据SIM卡自适应变化.
Settings中语言切换流程
当在系统设置中手动设置语言拖拽结束后,会调用updateLocalesWhenAnimationStops(ll)方法
- vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
public void updateLocalesWhenAnimationStops(final LocaleList localeList) {
if (localeList.equals(mLocalesToSetNext)) {
return;
}
// This will only update the Settings application to make things feel more responsive,
// the system will be updated later, when animation stopped.
LocaleList.setDefault(localeList);
mLocalesToSetNext = localeList;
final RecyclerView.ItemAnimator itemAnimator = mParentView.getItemAnimator();
itemAnimator.isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
@Override
public void onAnimationsFinished() {
if (mLocalesToSetNext == null || mLocalesToSetNext.equals(mLocalesSetLast)) {
// All animations finished, but the locale list did not change
return;
}
// 语言条目发生改变,调用到framework下的LocalePicker进行更新
LocalePicker.updateLocales(mLocalesToSetNext);
mLocalesSetLast = mLocalesToSetNext;
new ShortcutsUpdateTask(mContext).execute();
mLocalesToSetNext = null;
mNumberFormatter = NumberFormat.getNumberInstance(Locale.getDefault());
}
});
}
然后调用LocalePicker的updateLocales()方法进行更新
- frameworks/base/core/java/com/android/internal/app/LocalePicker.java
/**
* Requests the system to update the list of system locales.
* Note that the system looks halted for a while during the Locale migration,
* so the caller need to take care of it.
*/
@UnsupportedAppUsage
public static void updateLocales(LocaleList locales) {
if (locales != null) {
locales = removeExcludedLocales(locales);
}
// Note: the empty list case is covered by Configuration.setLocales().
try {
final IActivityManager am = ActivityManager.getService();
final Configuration config = am.getConfiguration();
// 切换后的语言信息更新到Configuration
config.setLocales(locales);
config.userSetLocale = true; // 手动设置的标志
am.updatePersistentConfigurationWithAttribution(config,
ActivityThread.currentOpPackageName(), null);
// Trigger the dirty bit for the Settings Provider.
BackupManager.dataChanged("com.android.providers.settings");
} catch (RemoteException e) {
// Intentionally left blank
}
}
又转入到ActivityManagerService中处理
- frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public void updatePersistentConfigurationWithAttribution(Configuration values,
String callingPackage, String callingAttributionTag) {
enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
enforceWriteSettingsPermission("updatePersistentConfiguration()", callingPackage,
callingAttributionTag);
if (values == null) {
throw new NullPointerException("Configuration must not be null");
}
int userId = UserHandle.getCallingUserId();
// 这里的mActivityTaskManager就是ActivityTaskManagerService
mActivityTaskManager.updatePersistentConfiguration(values, userId);
}
继续传递到ActivityTaskManagerService中处理updateConfigurationLocked()
- frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
final long origId =