Android(安卓)Settings ——language / locale 修改语言
看过就忘!为了照顾自己的痴呆脑,劳累双手记录一下。
packages/apps/Settings/AndroidManifest.xml
packages/apps/Settings/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
import android.os.LocaleList (全部 语言)
import com.android.internal.app.LocaleHelper
import com.android.internal.app.LocalePicker (已选 语言)
import java.util.Locale
private static String getLocaleNames(Context context) { final LocaleList locales = LocalePicker.getLocales(); final Locale displayLocale = Locale.getDefault(); return LocaleHelper.toSentenceCase( LocaleHelper.getDisplayLocaleList( locales, displayLocale, 2 /* Show up to two locales from the list */), displayLocale); }
libcore/ojluni/src/main/java/java/util/Locale.java
external/libgdx/backends/gdx/-backends-gwt/src/com/badlogic/gdx/backends/gwt/emu/jaba/util/Locale.java
frameworks/base/core/java/com/android/internalapp/LocalePicker.java
[UI 主view]
packages/apps/Settings/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
public void onCreate(Bundle icicle) { addPreferencesFromResource(R.xml.language_settings);}
packages/apps/Settings/res/xml/language_settings.xml/language_settings
packages/apps/Settings/src/com/android/settings/localepicker/LocaleListEditor.java
@Override public void onLocaleSelected(LocaleStore.LocaleInfo locale) { mAdapter.addLocale(locale); updateVisibilityOfRemoveMenu(); }
packages/apps/Settings/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java
void addLocale(LocaleStore.LocaleInfo li) { mFeedItemList.add(li); notifyItemInserted(mFeedItemList.size() - 1); doTheUpdate(); }
public void updateLocalesWhenAnimationStops(final LocaleList localeList) { final RecyclerView.ItemAnimator itemAnimator = mParentView.getItemAnimator(); itemAnimator.isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() { @Override public void onAnimationsFinished() { LocalePicker.updateLocales(mLocalesToSetNext); } }); }
frameworks/base/core/java/com/android/internalapp/LocalePicker.java
public static void updateLocales(LocaleList locales) { try { final IActivityManager am = ActivityManagerNative.getDefault(); final Configuration config = am.getConfiguration(); config.setLocales(locales); config.userSetLocale = true; am.updatePersistentConfiguration(config); // Trigger the dirty bit for the Settings Provider. BackupManager.dataChanged("com.android.providers.settings"); } catch (RemoteException e) { // Intentionally left blank } }
frameworks/base/core/java/android/app/ActivityManagerNative .java
static public IActivityManager getDefault() { return gDefault.get(); }
ActivityManagerNative 的 getDefault() ,返回的是远程服务对象 ActivityManagerServices.java 在本地的一个代理, 最终调用的是ActivityManagerServices.java 中的 updateCofiguration() 函数。
frameworks/base/core/java/android/app/IActivityManager.java
public void updatePersistentConfiguration(Configuration values) throws RemoteException;
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale, boolean persistent, int userId, boolean deferResume) { if (values != null) { Configuration newConfig = new Configuration(mConfiguration); changes = newConfig.updateFrom(values); if (changes != 0) { if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { final LocaleList locales = values.getLocales(); int bestLocaleIndex = 0; if (locales.size() > 1) { if (mSupportedSystemLocales == null) { mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); } bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); } SystemProperties.set("persist.sys.locale", locales.get(bestLocaleIndex).toLanguageTag()); LocaleList.setDefault(locales, bestLocaleIndex); mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, locales.get(bestLocaleIndex))); } } return kept; }
frameworks/base/core/java/android/content/res/Configuration.java
public @Config int updateFrom(@NonNull Configuration delta) { int changed = 0; fixUpLocaleList(); delta.fixUpLocaleList(); if (!delta.mLocaleList.isEmpty() && !mLocaleList.equals(delta.mLocaleList)) { changed |= ActivityInfo.CONFIG_LOCALE; mLocaleList = delta.mLocaleList; // delta.locale can't be null, since delta.mLocaleList is not empty. if (!delta.locale.equals(locale)) { locale = (Locale) delta.locale.clone(); // If locale has changed, then layout direction is also changed ... changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION; // ... and we need to update the layout direction (represented by the first // 2 most significant bits in screenLayout). setLayoutDirection(locale); } } if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0))) { changed |= ActivityInfo.CONFIG_LOCALE; userSetLocale = true; } return changed; }
target locale file : "persist.sys.locale" (data/property/persist.sys.locale)
2) 所有语言 文件
packages/apps/Settings/src/com/android/settings/localepicker/LocaleListEditor.java
private void configureDragAndDrop(View view) { mAddLanguage = view.findViewById(R.id.add_language); mAddLanguage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker( getContext(), LocaleListEditor.this, false /* translate only */); } }); }
frameworks/base/core/java/com/android/internalapp/LocalePickerWithRegion.java
public static LocalePickerWithRegion createLanguagePicker(Context context, LocaleSelectedListener listener, boolean translatedOnly) { LocalePickerWithRegion localePicker = new LocalePickerWithRegion(); localePicker.setListener(context, listener, /* parent */ null, translatedOnly); return localePicker; }
private boolean setListener(Context context, LocaleSelectedListener listener, LocaleStore.LocaleInfo parent, boolean translatedOnly) { final HashSet langTagsToIgnore = new HashSet<>(); if (!translatedOnly) { final LocaleList userLocales = LocalePicker.getLocales(); final String[] langTags = userLocales.toLanguageTags().split(","); Collections.addAll(langTagsToIgnore, langTags); } if (parent != null) { } else { mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore, null /* no parent */, translatedOnly); } return true; }
frameworks/base/core/java/com/android/internalapp/LocaleStore.java
public static Set getLevelLocales(Context context, Set ignorables, LocaleInfo parent, boolean translatedOnly) { fillCache(context); for (LocaleStore.LocaleInfo li : sLocaleCache.values()) { } return result; }
public static void fillCache(Context context) { for (String localeId : LocalePicker.getSupportedLocales(context)) { LocaleInfo li = new LocaleInfo(localeId); sLocaleCache.put(li.getId(), li); } }
frameworks/base/core/java/com/android/internalapp/LocalePicker.java
public static String[] getSupportedLocales(Context context) { return context.getResources().getStringArray(R.array.supported_locales); }
全部语言 file : frameworks/base/core/res/res/values/locale_config.xml
3) LocalePicker.getLocales()
frameworks/base/core/java/com/android/internalapp/LocalePicker.java
public static LocaleList getLocales() { try { return ActivityManagerNative.getDefault() .getConfiguration().getLocales(); } catch (RemoteException e) { // If something went wrong return LocaleList.getDefault(); } }
frameworks/base/core/java/android/content/res/Configuration.java
public @NonNull LocaleList getLocales() { fixUpLocaleList(); return mLocaleList; }
private void fixUpLocaleList() { if ((locale == null && !mLocaleList.isEmpty()) || (locale != null && !locale.equals(mLocaleList.get(0)))) { mLocaleList = locale == null ? LocaleList.getEmptyLocaleList() : new LocaleList(locale); } }
frameworks/base/core/java/android/os/LocaleList.java
private static final LocaleList sEmptyLocaleList = new LocaleList(); public LocaleList(@NonNull Locale... list) { if (list.length == 0) { mList = sEmptyList; mStringRepresentation = ""; } else { final Locale[] localeList = new Locale[list.length]; final HashSet seenLocales = new HashSet(); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.length; i++) { final Locale l = list[i]; if (l == null) { throw new NullPointerException("list[" + i + "] is null"); } else if (seenLocales.contains(l)) { throw new IllegalArgumentException("list[" + i + "] is a repetition"); } else { final Locale localeClone = (Locale) l.clone(); localeList[i] = localeClone; sb.append(localeClone.toLanguageTag()); if (i < list.length - 1) { sb.append(','); } seenLocales.add(localeClone); } } mList = localeList; mStringRepresentation = sb.toString(); } }
更多相关文章
- 修改android默认时区语言
- Android之国际化(在程序内部强制转换语言)
- 第1章 Java基本概念及环境配置——FAQ1.04 Android与Java语言有
- [zz] Android(安卓)初始化语言(Android(安卓)init Language翻译)
- Android(安卓)应用(中英文)切换
- AIDL(android 接口描述语言)
- Android获取语言及地区总结
- Android(安卓)AIDL接口定义语言
- 最近Android挺火啊,都没有什么感想吗