Android BLE扫描被意外切换至机会模式的原因分析与解决方案咨询
Android BLE扫描莫名停止的问题分析与解决
你的猜测是否正确?
完全正确。当应用被强制杀死时,stopScan()无法正常调用,ScanManager中残留的MSG_SCAN_TIMEOUT消息不会被清理。当应用重启后,如果系统为新的扫描会话分配了与之前相同的scannerId,残留的超时消息触发时,会直接将新启动的扫描切换至机会扫描模式,导致扫描效率大幅下降,表现为扫描“停止”。
这是否属于Android系统BUG?
是的,这属于Android系统的设计缺陷。原代码注释明确要求“同一时间只存在一个超时消息”,但新版本源码移除了启动扫描时清理旧消息的逻辑,且未处理应用异常终止后残留消息的场景,属于边缘场景的处理遗漏。
可行的解决办法
- 使用全新的ScanCallback实例启动扫描
系统的scannerId与ScanCallback实例绑定,每次启动扫描时创建全新的ScanCallback对象(业务逻辑可以封装到独立类中,在回调方法里调用),让系统分配新的scannerId,避开残留消息关联的旧ID。 - 启动扫描前调用一次无效的stopScan
在每次启动扫描前,调用stopScan(new ScanCallback() {})。该调用会返回false(因为没有对应扫描在运行),但会触发ScanManager的handleStopScan逻辑,自动清理残留的超时消息。 - 补充进程状态监听,尽量主动清理扫描
通过ProcessLifecycleOwner监听应用进入后台的极端状态,或在Application.onTerminate()中调用stopScan(),覆盖部分正常退出场景,减少残留消息的产生。但该方法无法处理系统强杀、用户手动划掉的情况,仅作为补充。 - 版本适配
仅在Android 7及以上版本应用上述方案,低版本保留原定时重启逻辑即可,因为低版本ScanManager会在启动扫描时清理旧的超时消息。
内容的提问来源于stack exchange,提问作者Ricky Mo
相关产品推荐
相关产品推荐

