1. 项目背景与需求解析
在Android设备定制开发领域,修改蓝牙设备名称是一项基础但至关重要的需求。MTK6737作为联发科面向中低端市场的四核处理器方案,搭载Android Q系统时,其蓝牙名称修改流程与早期版本存在显著差异。最近在为一个车载设备项目适配时,就遇到了必须修改出厂蓝牙名称的需求——客户要求将默认的"MTK-BT-Device"变更为"CarKit-XXXX"格式。
这个看似简单的需求背后,实际上涉及Android Q的蓝牙服务架构变更、MTK平台特有的硬件抽象层实现,以及系统属性管理的权限控制。不同于普通应用层通过BluetoothAdapter.setName()的修改方式,系统级的默认名称修改需要深入Framework层和Vendor实现。
2. 技术方案选型分析
2.1 Android Q蓝牙架构变化
Android Q(10)对蓝牙子系统进行了重大重构,主要变化包括:
- 引入新的Bluetooth堆栈架构(Gabeldorsche)
- 蓝牙服务从system_server迁移到独立进程bluetooth
- 名称存储位置从Settings.Global迁移到蓝牙服务私有存储
这导致传统修改方式失效:
java复制// Android P及之前有效的方式
BluetoothAdapter.getDefaultAdapter().setName("NewName");
Settings.Global.putString(getContentResolver(), "device_name", "NewName");
2.2 MTK平台特殊实现
MTK6737在Q版本上保留了部分兼容层,但核心逻辑已变更:
-
蓝牙名称初始化流程:
- 优先读取ro.product.model
- 其次读取persist.bluetooth.name
- 最后回退到ro.bluetooth.name
-
硬件抽象层关键文件:
bash复制
/vendor/mediatek/proprietary/hardware/connectivity/bluetooth/driver/bluetooth.c /system/bt/btif/src/btif_dm.cc
3. 具体实现步骤
3.1 系统属性修改
通过修改build.prop是最稳定的方案:
bash复制# 在device/mediatek/mt6737/device.mk中添加
PRODUCT_PROPERTY_OVERRIDES += \
ro.bluetooth.name=CarKit-$(shell echo $(TARGET_PRODUCT) | cut -d'_' -f2)
或者运行时修改:
bash复制adb root
adb shell setprop persist.bluetooth.name "CarKit-V1"
adb shell stop bluetooth
adb shell start bluetooth
3.2 Framework层修改
对于需要动态控制的场景,需修改以下关键类:
java复制// packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
public synchronized void setName(String name) {
// 添加MTK平台特殊处理
if (TextUtils.isEmpty(name)) {
name = SystemProperties.get("persist.bluetooth.name",
SystemProperties.get("ro.bluetooth.name", ""));
}
mName = name;
}
3.3 Vendor层适配
MTK特有的初始化脚本需要调整:
bash复制# 在vendor/mediatek/proprietary/scripts/bluetooth/bt_init.sh中修改:
BT_NAME=`getprop persist.bluetooth.name`
if [ "$BT_NAME" = "" ]; then
BT_NAME=`getprop ro.product.model`
setprop persist.bluetooth.name "$BT_NAME"
fi
4. 验证与调试技巧
4.1 修改效果验证
bash复制adb shell dumpsys bluetooth_manager | grep "name:"
adb shell getprop | grep bluetooth.name
4.2 常见问题排查
-
修改后名称不更新:
- 检查SELinux策略:
adb shell dmesg | grep avc - 添加策略规则:
te复制allow bluetooth system_prop:property_service set;
- 检查SELinux策略:
-
MTK平台特有日志获取:
bash复制adb shell logcat -b all | grep -iE "bt_mtk|btif" -
蓝牙服务崩溃恢复:
bash复制
adb shell killall com.android.bluetooth
5. 生产环境优化建议
-
OTA兼容性处理:
- 在升级脚本中保留自定义名称:
bash复制if grep -q "persist.bluetooth.name" /system/build.prop; then old_name=$(getprop persist.bluetooth.name) sed -i "s/ro.bluetooth.name=.*/ro.bluetooth.name=$old_name/" $NEW_SYSTEM/build.prop fi -
多语言支持方案:
xml复制<!-- 在frameworks/base/core/res/res/values/config.xml中配置 --> <string-array name="config_btNameFormat"> <item>CarKit-%s</item> <item>车载设备-%s</item> </string-array> -
功耗优化:
- 避免频繁名称更新触发蓝牙重新广播
- 设置合理的广播间隔:
java复制// 在AdapterService.java中修改 setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE, 2000); // 2秒间隔
6. 扩展应用场景
-
批量生产差异化命名:
python复制# 通过SN号生成唯一名称 import hashlib sn = get_serial_number() bt_name = f"CarKit-{hashlib.md5(sn.encode()).hexdigest()[:4]}" update_build_prop(bt_name) -
动态名称切换实现:
java复制// 在BluetoothManagerService.java中添加 public void setDynamicName(String suffix) { String base = getDefaultName(); mAdapterProperties.setName(base + "-" + suffix); } -
与WiFi热点名称联动:
bash复制# 在init.rc中添加触发器 on property:persist.bluetooth.name=* setprop persist.wifi.hotspot.name ${persist.bluetooth.name}
关键提示:MTK平台修改后必须执行
sync命令确保写入Flash,否则重启可能丢失配置
通过这个项目的实践,发现Android Q在蓝牙子系统上的改动确实带来了不少适配工作量,特别是像MTK这样的第三方平台,需要同时考虑AOSP标准实现和厂商自定义部分。建议在类似项目开发时,提前通过adb shell dumpsys bluetooth_manager完整分析当前蓝牙服务状态,再针对性修改相应层级。