1. 项目背景与需求解析
在Android设备定制开发中,蓝牙名称的默认设置是一个常见的客户需求。最近接手了一个MTK平台Android 12-13系统的定制项目,客户要求将默认蓝牙名称从系统默认值改为"KS-320MKS"。这个看似简单的需求,实际上涉及到Android蓝牙架构的多个层级和模块。
核心需求可以分解为三个具体场景:
- 在"设置-已连接设备-与新设备配对"界面中,Android设备名称需显示为客户定制的"KS-320MKS"
- 首次点击设备名称时,默认显示客户定制名称且允许用户修改
- 无论修改前后,手机端搜索到的设备蓝牙名称都应正确显示默认值或用户修改后的值
2. 实现效果展示
修改后的实际效果如下图所示:



3. 关键修改文件定位
实现这个功能需要修改的核心文件位于:
code复制frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
此外还需要关注以下几个关键类:
- BluetoothDeviceNamePreferenceController
- DiscoverableFooterPreferenceController
- AdapterProperties
- BluetoothPairingDetail
4. 完整实现方案
4.1 蓝牙名称设置入口点分析
Android系统中蓝牙名称的默认值设置主要通过BluetoothAdapter类实现。具体流程如下:
- 系统首次启动时,会调用BluetoothAdapter的getName()方法获取默认名称
- 如果没有用户自定义名称,则返回系统默认值
- 我们需要修改的就是这个默认值的获取逻辑
关键代码位置:
java复制// BluetoothAdapter.java
public String getName() {
try {
return mManagerService.getName();
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return null;
}
4.2 具体实现步骤
步骤1:修改默认名称返回值
在BluetoothAdapter.java中找到getName()方法调用链,最终定位到AdapterProperties类中的name字段。我们需要在系统初始化时就将这个字段设置为客户要求的"KS-320MKS"。
修改建议:
java复制// 在AdapterProperties初始化代码中添加
this.name = "KS-320MKS"; // 客户定制名称
步骤2:处理UI显示逻辑
蓝牙设置界面中,设备名称显示主要受以下控制器影响:
- BluetoothDeviceNamePreferenceController - 负责名称编辑界面
- DiscoverableFooterPreferenceController - 负责"向其他设备显示为"文本
需要确保这两个控制器都能正确获取我们设置的默认值:
java复制// BluetoothDeviceNamePreferenceController.java
protected void updateDeviceName() {
final String deviceName = mBluetoothAdapter.getName();
if (deviceName != null) {
mPreference.setSummary(deviceName);
mPreference.setVisible(true);
} else {
mPreference.setVisible(false);
}
}
步骤3:处理名称持久化存储
Android会将用户修改后的蓝牙名称存储在Settings.Global中,键值为"bluetooth_name"。我们需要确保:
- 首次使用时返回我们的默认值
- 用户修改后能正确保存和读取
java复制// 修改后的名称获取逻辑
public String getName() {
String name = Settings.Global.getString(getContext().getContentResolver(), "bluetooth_name");
return name != null ? name : "KS-320MKS"; // 默认返回定制名称
}
4.3 蓝牙名称传递架构解析
完整的蓝牙名称传递流程涉及Android蓝牙栈的多个层级:
- 应用层:Settings应用通过BluetoothAdapter API获取名称
- Framework层:BluetoothManagerService处理跨进程调用
- JNI层:通过BluetoothService与底层蓝牙协议栈交互
- HAL层:最终通过蓝牙芯片固件广播名称
关键类调用关系:
code复制BluetoothAdapter -> IBluetoothManager -> BluetoothManagerService
-> IBluetooth -> BluetoothService -> AdapterProperties
5. 源码深度解析
5.1 蓝牙名称获取流程
完整的getName()调用栈分析:
java复制// BluetoothAdapter.java
public String getName() {
try {
return mManagerService.getName(); // 跨进程调用
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return null;
}
// BluetoothManagerService.java
public String getName() {
return synchronousGetName();
}
private String synchronousGetName() {
if (mBluetooth != null) {
try {
return mBluetooth.getName(); // 调用IBluetooth接口
} catch (RemoteException e) {
Log.e(TAG, "getName(): Unable to get name", e);
}
}
return null;
}
// BluetoothService.java (通过IBluetooth.aidl定义)
public String getName() {
return mAdapterProperties.getName(); // 最终获取名称
}
5.2 名称变更通知机制
当蓝牙名称发生变化时,系统通过回调机制通知各模块:
- 底层btif_dm.cc检测到名称变化
- 通过JNI调用通知Java层
- AdapterProperties触发propertyChange回调
- 最终通知注册的监听器更新UI
关键回调代码:
cpp复制// btif_dm.cc
static void btif_update_device_name(const char* bd_name) {
// 通过JNI回调到Java层
sBluetoothInterface->set_adapter_property(&prop);
}
6. 关键问题与解决方案
6.1 问题1:修改后名称不生效
现象:代码修改后,蓝牙名称仍然显示系统默认值
排查步骤:
- 确认修改的代码确实被编译进系统镜像
- 检查是否有其他模块覆盖了我们的默认值设置
- 查看logcat中蓝牙相关的日志
解决方案:
在AdapterProperties初始化后强制设置一次名称:
java复制mAdapterProperties.setName("KS-320MKS");
6.2 问题2:名称显示不一致
现象:部分界面显示定制名称,部分显示系统默认名称
原因:不同界面可能缓存了名称值,没有及时更新
解决方案:
在BluetoothDeviceNamePreferenceController中添加强制刷新逻辑:
java复制public void onBluetoothStateChanged(int bluetoothState) {
updateDeviceName(); // 蓝牙状态变化时强制刷新
}
7. 扩展知识点
7.1 蓝牙名称长度限制
根据蓝牙核心规范:
- 蓝牙名称最大长度为248字节
- 实际显示时通常限制为40个字符左右
- 建议客户定制名称不超过30个字符
7.2 多语言支持处理
如果需要支持多语言蓝牙名称,可以:
- 在res/values-xx/strings.xml中定义不同语言版本
- 在代码中根据系统语言动态获取:
java复制String bluetoothName = getResources().getString(R.string.bt_default_name);
7.3 厂商特定实现差异
不同芯片平台可能有特殊要求:
- 高通平台可能需要修改bt_config.conf文件
- MTK平台有时需要在alps/device/mediatek/common中修改
- 展讯平台可能有自己的名称设置接口
8. 最佳实践建议
- 版本兼容性处理:
java复制// 根据不同Android版本采用不同设置方式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// Android 13+的新API
} else {
// 旧版本实现
}
- 调试技巧:
- 使用以下命令实时监控蓝牙名称变化:
bash复制adb logcat | grep -E "BluetoothAdapter|AdapterProperties"
- 测试要点:
- 验证蓝牙开关多次后名称是否保持正确
- 测试恢复出厂设置后默认名称是否正确
- 验证与其他品牌设备的兼容性
在实现过程中,发现MTK平台在Android 12和13上对蓝牙名称的处理有细微差异。特别是在系统升级场景下,需要特别注意名称的持久化存储逻辑。建议在修改后执行完整的蓝牙功能测试,包括配对、连接、文件传输等所有常用功能。