记一次 RK3568 Android 13 蓝牙反复重启问题的排查与修复

目录

​​​背景

怎么定位的

第一步:确认底层是否正常

第二步:抓崩溃日志

第三步:确认崩溃链路

第四步:尝试修复

怎么修改的

总结


背景

项目基于 RK3568 + Android 13 进行系统裁剪,目标是去除不必要的系统应用以减小镜像体积。在移除联系人应用后,发现蓝牙功能异常:能扫描到设备,但无法稳定开启,日志中大量出现 [BT_RFKILL]: bt shut off power 与 bt turn on power 的循环。

一开始怀疑是固件缺失、HAL 库被删或驱动问题,但检查后发现 rtl8822cs_fw、rtl8822cs_config、libbt-vendor-realtek.so、android.hardware.bluetooth@1.0-impl.so 等文件全部存在,SELinux 策略、UART 权限也正常。问题显然不在底层。

怎么定位的

第一步:确认底层是否正常

抓取 dmesg 和 logcat,发现蓝牙 HAL 其实已经成功初始化:

  • 固件下载成功:vendor lib fwcfg completed

  • HCI 初始化成功:android.hardware.bluetooth@1.0-impl: OnFirmwareConfigured result: 0

说明蓝牙芯片、固件、HAL 都是好的。问题在上层。

第二步:抓崩溃日志

用以下命令过滤 AndroidRuntime 崩溃:

bash 复制代码
logcat -b all -s AndroidRuntime:E | grep -i "BluetoothPbapService"

日志中反复出现同一个异常:

bash 复制代码
java.lang.RuntimeException: Unable to start service com.android.bluetooth.pbap.BluetoothPbapService ...
java.lang.SecurityException: Failed to find provider com.android.contacts for user 0; 
expected to find a valid ContentProvider for this authority

根因清晰了 :BluetoothPbapService 启动时需要访问 com.android.contacts 的 ContentProvider,但联系人应用被裁剪掉了,Provider 不存在,服务启动失败,抛出的 SecurityException 直接导致整个蓝牙进程崩溃。

第三步:确认崩溃链路

继续抓 BluetoothManagerService 的日志:

bash 复制代码
logcat -b all -s BluetoothManagerService:D

可以看到完整的崩溃链路:

  1. 蓝牙服务启动 → MESSAGE_BLUETOOTH_SERVICE_CONNECTED

  2. PBAP 服务启动失败,进程崩溃 → MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED

  3. 系统尝试重启蓝牙服务 → MESSAGE_RESTART_BLUETOOTH_SERVICE: retry count=1

  4. 再次崩溃,循环往复

这就是蓝牙状态反复跳变的根本原因。

第四步:尝试修复

第一次尝试(失败) :设置 persist.bluetooth.pbap.server.enabled=false。

结果重启后无效。用 getprop | grep -i pbap 检查发现:

bash 复制代码
[bluetooth.profile.pbap.server.enabled]: [true]   ← 真正生效的属性
[persist.bluetooth.pbap.server.enabled]: [false]  ← 无效属性

原来 Android 13 蓝牙栈读取的是 bluetooth.profile.pbap.server.enabled,而不是带 persist. 前缀的那个。

第二次尝试(成功):设置正确的属性:

bash 复制代码
setprop bluetooth.profile.pbap.server.enabled false

重启蓝牙后,日志中不再出现 BluetoothPbapService 崩溃,蓝牙状态稳定停留在 ON,问题解决。

怎么修改的

setprop 只在当前运行有效,因为 bluetooth.profile.pbap.server.enabled 不带 persist. 前缀,重启后会恢复默认值 true。要永久生效,必须固化到 SDK 源码。

在设备的 init.rc(如 device/rockchip/rk356x/init.rk356x.rc)中添加:

bash 复制代码
on boot
    setprop bluetooth.profile.pbap.server.enabled false

on boot 触发时,所有 build.prop 都已加载完毕,此时 setprop 的值不会再被覆盖,蓝牙服务后续读取到的就是 false。

总结

这次问题的本质是系统裁剪时移除了联系人应用,但没有同步关闭依赖它的蓝牙 PBAP Profile,导致上层 Java 服务启动失败并拖垮整个蓝牙进程。

几个关键经验:

  1. 裁剪系统应用时要检查依赖链。删除一个应用可能影响其他模块,尤其是蓝牙、通话、短信这类有 Profile 依赖的系统服务。

  2. Android 属性前缀很重要 。persist. 前缀的属性才会持久化,不带前缀的只影响当前运行。设置属性前先用 getprop | grep 确认属性名是否正确。

  3. 定位问题要分层 。先从 dmesg 确认底层(驱动、固件、HAL),再看 logcat 上层(Java 服务、系统进程),避免在错误的方向浪费时间。

  4. setprop 只适合临时验证,固化配置要改源码 。找到正确的属性名后,最终方案是写进设备的 init.rc中,保证每次开机默认值正确。

  5. 崩溃日志里的异常栈是最直接的线索 。SecurityException: Failed to find provider com.android.contacts 这一行就已经指明了根因,剩下的只是顺着它往下查。

相关推荐
HQL_seven3 小时前
【Android】BroadcastReceiver 详解
android
_祝你今天愉快5 小时前
Paint Cavans高级绘制:[二] Paint-滤镜,XFERMODE
android
小乖写代码5 小时前
字段获取代码(Android) · Android Input Examples
android·whatsapp·账号注册
booboosui5 小时前
停一个活只有杀进程:界面上少了「说点要求」
android
传奇开心果编程7 小时前
【Flutter踩坑排雷】第28课:平台目录缺失与修复坑|`flutter create` 的“重建”与“覆盖”边界
android·flutter·ios·移动开发·跨平台·dart·声明式ui
longxibo17 小时前
【AIBIZ低代码平台:能长出业务系统的平台】
android·低代码·rxjava
AI_Gump1 天前
Harness篇|DeepSeek Harness 上手机:五条安卓移植路线与 App 内 Linux 拆解
android·linux·人工智能·智能手机·deepseek
疯华整猫1 天前
否决 Flutter 提案那天,我发现自己也说不清 Framework 管什么
android
传奇开心果编程2 天前
【Flutter踩坑排雷】第25课:ScrollController 误用坑|跳转失效、监听泄漏与“控制器未附加”
android·flutter·ios·移动开发·跨平台·dart·声明式ui
慕容雪_2 天前
Capacitor8-Android打包完整手册
android·打包·capacitor