语言切换知识库 · 00-README(索引)

MiCarSettings「切换系统语言」专题知识库入口。 建库:2026-07-19 | 基线机型:fermi (flavor=xcd, region=cn) 维护方式:分篇 + mermaid + 文件:行号;本文件是导航,详情进各篇。


一句话结论

国内版(ro.micar.build.region=cn)在「系统→通用」里看不到「系统语言」入口,是产品有意裁剪(UniversalSettingsFragment 运行时移除),不是 bug。切语言有三条路:① 彩蛋(关于→连点内核版本 10 次,国内可用、即时生效)② adb(改 system_locales + reboot)③ 海外版才有 UI 入口。核心坑:权威落点是 Settings.System.system_localespersist.sys.locale 只是 fallback——只改 prop 重启必被覆盖回旧值。


全景图

flowchart LR
    subgraph 触发["切换语言的三条路径"]
        E1["① 彩蛋<br/>关于→内核版本点10次<br/>LanguageUtils.showTipToast<br/>中英互切·即时生效<br/>国内cn可用/ECE隐藏"]
        E2["② adb<br/>settings put system system_locales<br/>+ reboot<br/>任意机型·需root或debug"]
        E3["③ UI入口<br/>系统→通用→系统语言<br/>SystemLanguageDialogActivity<br/>仅海外版可见"]
    end

    subgraph 归一["全部归一到 framework 单一入口"]
        LP["com.android.internal.app<br/>LocalePicker.updateLocale<br/>(adb 例外:直接写 system_locales)"]
    end

    subgraph 落点["三处存储"]
        SL["Settings.System.system_locales<br/>★ 权威 · 跨重启"]
        PP["persist.sys.locale<br/>fallback · 镜像"]
        CF["运行时 Configuration<br/>派生 · 进程内"]
    end

    subgraph 副作用["切换后"]
        BR["ACTION_LOCALE_CHANGED 广播"]
        VSM["LocaleChangedReceiver<br/>→ VoiceSearchManager.onLocaleChanged<br/>语音搜索重解析"]
    end

    E1 --> LP
    E3 --> LP
    LP --> SL
    LP --> PP
    LP --> CF
    E2 --> SL
    SL -- "reboot后AMS读取" --> CF
    CF --> BR
    BR --> VSM

    style SL fill:#d4edda,stroke:#28a745
    style PP fill:#fff3cd,stroke:#ffc107
    style E1 fill:#e1f5ff,stroke:#0a6

文档清单

#文档回答的问题
01切换全链路时序用户点「系统语言」后,从 Controller → DialogActivity → Adapter → LocalePicker.updateLocale 的完整时序、状态机、防双击、文案
02Android Locale 体系与落点为什么 setprop persist.sys.locale 改了重启还是中文?三个存储点、framework 链路、优先级决策树(含可验证性说明)
03 Region 裁剪机制为什么 XCD cn 看不到入口?ro.micar.build.region 判定、国内裁剪 vs ECE 物理裁剪、Flavor/Region 正交
04adb 实操与排查手册命令清单、fermi 实战复盘、4 个入口盘点(含彩蛋)、排查决策树、常见坑
_对抗审查记录建库时的对抗审查过程(13 条问题 + 修正),留档供追溯

速查:三个关键事实

  1. 权威 locale 源 = Settings.System.system_locales(不是 persist.sys.locale)。
    • 切:adb shell settings put system system_locales en-US && adb reboot
    • 查(三连,以第三个为准):
      adb shell getprop persist.sys.locale
      adb shell settings get system system_locales
      adb shell dumpsys activity | grep -oE '\[[a-z]{2}_[A-Z]{2,3}\]' | head -1
  2. 国内/海外判定 = ro.micar.build.region(cn/global/eu/ece,空也算国内)。adb shell getprop ro.micar.build.region 一行查清。
  3. 国内版也能切语言——彩蛋入口(关于→内核版本点 10 次)走 LanguageUtils.showTipToastLocalePicker.updateLocale,即时生效、无需 reboot;ECE 版因 hiddenFeatures="lemans_ece" 隐藏内核条目而点不到。

速查:项目内 4 个切换入口

入口文件国内可用
① 设置→通用→系统语言SystemLanguagePreferenceController.kt:46SystemLanguageDialogActivity.kt:52否(被移除)
② 开机引导选语言ProvisionLanguageDialogActivity.kt:100是(provision 拉起)
③ 显示设置老入口LanguagePickerPrefController.java:46已废弃(XML 注释停用)
④ 彩蛋:内核版本点 10 次KernelVersionPreferenceController.java:80LanguageUtils.java:26是(cn 可用,ECE 隐藏)

边界

覆盖:MiCarSettings 应用内「切换系统语言」的全部代码路径、Locale 落点机制、Flavor/Region 裁剪、adb 调试与排查。

不覆盖(如需请另建专题):

  • 各语言字符串资源的翻译完整性(values-de/fr/... 覆盖率)
  • 多用户/多账号下的 per-user locale 隔离(AOSP 行为,本仓不可验证,见 02 篇 §10)
  • OTA 升级时 system_locales 是否被强制回写出厂值(待实测)
  • framework 侧 LocalePicker/AMS/SettingsProvider 的逐行源码(非本仓,02 篇基于 AOSP 描述)

相关文件清单(核心)

  • 入口/弹窗/列表:settingsPage/settingsSystem/src/main/java/com/android/car/settings/universal/SystemLanguagePreferenceController.kt / SystemLanguageDialogActivity.kt / SystemLanguageConfig.kt / SystemLanguageAdapter.kt / LocaleInfoWrapper.kt / ProvisionLanguageDialogActivity.kt / UniversalSettingsFragment.java
  • 读 locale:base/settingsBaseLib/src/main/java/com/android/micar/settings/utils/LocaleUtils.kt
  • 彩蛋:settingsPage/settingsSystem/.../system/KernelVersionPreferenceController.java + .../utils/LanguageUtils.java
  • 监听变更:app/src/main/java/com/android/car/settings/miauto/LocaleChangedReceiver.kt(manifest 注册 app/src/main/AndroidManifest.xml:1583-1589
  • Region 判定:base/settingsBaseLib/.../DeviceUtil.java + .../views/MiCarSettings.java
  • 两套 XML:settingsPage/settingsSystem/src/main/res/xml/miauto_universal_settings_fragment.xml(主)+ _ece.xml(ECE 精简)