本文面向需要在 Android 10(AOSP) 上定制「首次开机 / 新用户」时蓝牙与 Wi‑Fi 默认开关的工程师,说明 系统如何把 defaults.xml 写进全局设置 、产品 Overlay 如何生效 ,以及 应用侧如何读取。
1. 配置改哪里
1.1 平台默认值(所有产品共用)
文件:android10/frameworks/base/packages/SettingsProvider/res/values/defaults.xml

其中与本文相关的项(节选):
xml
<bool name="def_bluetooth_on">true</bool>
<bool name="def_wifi_on">false</bool>
含义:def_bluetooth_on / def_wifi_on 仅在 SettingsProvider 初始化全局设置 时作为 资源布尔值 参与写入;不是 给应用直接读取的 R 资源名。
1.2 产品 / 形态 Overlay(例如车载 Car)
文件:android10/packages/services/Car/car_product/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
示例(与平台默认不同处会覆盖合并后的资源):
xml
<bool name="def_bluetooth_on">false</bool>
<bool name="def_wifi_on">false</bool>
构建时,SettingsProvider 包的 Resources 会按 资源合并规则 叠加 overlay,最终 R.bool.def_bluetooth_on / R.bool.def_wifi_on 解析为 合并后的值。
2. 系统执行逻辑(核心)
2.1 数据落在哪里
- 逻辑键名在
android.provider.Settings.Global中定义:- 蓝牙:
Settings.Global.BLUETOOTH_ON,字符串键bluetooth_on - Wi‑Fi:
Settings.Global.WIFI_ON,字符串键wifi_on
- 蓝牙:
- 存储形态在 Android 10 中已由早期纯 SQLite 演进为 内存 + 持久化(如 XML) ;但 首次种子数据 仍与
DatabaseHelper中「从defaults.xml载入」的路径一致,理解这段代码即可把握「首次默认值」来源。
2.2 从资源到 Global 表项
DatabaseHelper.loadGlobalSettings() 将 def_* 通过 loadBooleanSetting 写入 global 命名空间对应键,布尔值被写成 "1" / "0" 字符串:
2485:2492:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
loadBooleanSetting(stmt, Settings.Global.WIFI_ON,
R.bool.def_wifi_on);
loadBooleanSetting(stmt, Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
R.bool.def_networks_available_notification_on);
loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,
R.bool.def_bluetooth_on);
2652:2655:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
loadSetting(stmt, key,
mContext.getResources().getBoolean(resid) ? "1" : "0");
}
DatabaseHelper 中另有注释说明:后续升级与持久化细节由 SettingsProvider.UpgradeController 等路径处理,不要再往旧式 DB 升级步骤里堆全局项 ------但 def_bluetooth_on / def_wifi_on → Global 键 的对应关系不变。
2.3 流程图(配置生效链路)
编译期: defaults.xml 基础包
可选 Overlay 合并 Resources
SettingsProvider 进程 Context.getResources
DatabaseHelper.loadGlobalSettings 等初始化路径
写入 Global: wifi_on / bluetooth_on 值为 0 或 1
系统服务根据设置启停 WiFi / Bluetooth
应用
Settings.Global.getInt(..., WIFI_ON / BLUETOOTH_ON)
2.4 与「真实射频状态」的区别
Settings.Global.WIFI_ON/BLUETOOTH_ON:系统保存的 设置项 (期望开关),首次开机由def_*种子决定,之后可被用户、设置 App、系统策略改写。WifiManager/BluetoothAdapter的 isEnabled() :更接近 当前栈上实际状态,可能与设置项短暂不一致(例如正在切换、策略限制、飞行模式等)。
做功能联调时,二者建议对照看。
3. app应用如何读取
应用 不要 去解析 defaults.xml;应读 已持久化的 Global 设置。
3.1 读取 Global 键(与 def_* 对应)
java
import android.provider.Settings;
// Wi‑Fi 设置项:1 开,0 关(键名 wifi_on)
int wifiOn = Settings.Global.getInt(
getContentResolver(),
Settings.Global.WIFI_ON,
0);
// 蓝牙设置项:1 开,0 关(键名 bluetooth_on)
int btOn = Settings.Global.getInt(
getContentResolver(),
Settings.Global.BLUETOOTH_ON,
0);
3.2 若需「硬件是否已开」
- Wi‑Fi:
WifiManager.isWifiEnabled()(注意 Deprecated 与版本差异,新项目可按官方推荐方式封装)。 - 蓝牙:
BluetoothAdapter.isEnabled()(需合适权限与机型适配)。
3.3 权限与可见性
Settings.Global 部分键对 普通应用 可能存在 读限制或行为差异 (与签名、权限、AppOps 策略有关)。系统 / 特权应用 通常不受限。若线上出现 SecurityException,需在发布签名域内申请对应能力或改用公开 API(如上述 WifiManager / BluetoothAdapter)。
4. 修改配置后「为什么没变」------排查要点
-
是否已写过 Global
def_*主要在 初始化 / 首次写入 时起作用。若设备上wifi_on/bluetooth_on已有历史值 ,仅改defaults.xml再 OTA/刷机 不清 data 时,可能仍显示旧值。 -
Overlay 是否进当前 lunch 的产品
确认当前编译的
PRODUCT_PACKAGE_OVERLAYS(或等价机制)是否包含你的car_product/overlay/...路径,且make/soong未缓存旧资源(必要时清理相关模块)。 -
飞行模式与
AIRPLANE_MODE_RADIOS默认飞机会关掉列表中的射频;
defaults.xml里还有def_airplane_mode_radios等与无线电相关的项,可能与「用户感知到的首次状态」叠加,需一并核对:
android10/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
5. 蓝牙与 Wi‑Fi:重叠逻辑(一次说明,两处适用)
以下对 蓝牙 与 Wi‑Fi 完全同构 ,仅键名与 def_* 资源名不同:
| 环节 | 蓝牙 | Wi‑Fi |
|---|---|---|
defaults.xml 资源 |
def_bluetooth_on |
def_wifi_on |
Settings.Global 常量 |
BLUETOOTH_ON(bluetooth_on) |
WIFI_ON(wifi_on) |
| 写入函数 | loadBooleanSetting(..., BLUETOOTH_ON, R.bool.def_bluetooth_on) |
loadBooleanSetting(..., WIFI_ON, R.bool.def_wifi_on) |
| 应用读取 | Settings.Global.getInt(..., BLUETOOTH_ON, def) |
Settings.Global.getInt(..., WIFI_ON, def) |
| 典型「真实状态」API | BluetoothAdapter.isEnabled() |
WifiManager 相关 API |
Wi‑Fi 默认开启 :将对应产品 overlay 或平台 defaults.xml 中的 def_wifi_on 设为 true ,重新编译刷机;并理解第二节「仅影响首次种子 / 未覆盖已有 data」的限制。蓝牙默认关闭 同理改 def_bluetooth_on 为 false。
6. 小结清单(下次改配置直接用)
- 改
android10/.../SettingsProvider/res/values/defaults.xml(平台默认)或 产品 overlay 下同路径文件。 - 确认
def_bluetooth_on/def_wifi_on与Settings.Global.BLUETOOTH_ON/WIFI_ON的映射关系(见DatabaseHelper.loadGlobalSettings)。 - 应用侧用
Settings.Global.getInt读设置项;要射频实况用WifiManager/BluetoothAdapter。 - 若改完未见效:查 是否已有持久化值 、overlay 是否参与当前产品编译 、飞行模式等相关默认项。