Android 11及以上系统后台模式下蓝牙无法扫描周边设备如何解决
安卓11及以上后台BLE扫描异常解决方案
0. 补充权限配置
如果你的app不需要通过BLE扫描结果推导物理位置,在manifest的蓝牙扫描权限中添加标记,可免除位置权限相关的后台限制:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" />
如果确实需要位置信息,确认用户已经手动授予了ACCESS_BACKGROUND_LOCATION权限,安卓11开始这个权限必须用户主动在设置页开启,无法通过普通权限弹窗申请。
1. 修正扫描过滤配置
安卓11开始,系统对后台无过滤的BLE扫描做了强制拦截,空的ScanFilter会直接导致后台扫描结果被丢弃,必须明确指定扫描过滤条件:
val scanFilter = ScanFilter.Builder() .setDeviceName("BIBO 1") // 不要注释,明确指定要匹配的设备名 // 也可以补充指定服务UUID等过滤条件 .build() scanFilters.add(scanFilter)
2. 调整扫描参数适配后台策略
后台扫描必须使用符合系统后台限制的扫描模式,避免被系统节流:
settings = ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) // 后台必须用低功耗模式 .setMatchMode(ScanSettings.MATCH_MODE_STICKY) // 提高后台设备匹配成功率 .build()
3. 改用PendingIntent方式触发扫描
后台运行时不要使用普通的ScanCallback回调,系统会在app退后台后很快冻结回调,改用PendingIntent方式让系统代为管理扫描,检测到设备时主动唤醒app:
// 先构造接收扫描结果的PendingIntent val intent = Intent(context, YourScanReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE ) // 启动扫描 mLEScanner?.startScan(scanFilters, settings, pendingIntent)
之后在广播接收器里处理扫描结果即可。
4. 补充前台服务配置
如果需要长时间后台扫描,必须将扫描逻辑放到前台服务中,安卓12及以上还需要在manifest中声明前台服务类型:
<service android:name=".YourBleScanService" android:foregroundServiceType="connectedDevice" />
启动服务时需要弹出常驻通知,符合前台服务的规范。
5. 适配厂商定制系统限制
小米、华为、OPPO、vivo等国产安卓定制系统都有额外的后台限制,需要引导用户手动开启以下权限:
- 允许app后台活动
- 关闭电池优化(将app加入电池白名单)
- 允许蓝牙后台运行权限
内容的提问来源于stack exchange,提问作者Bolt UIX
相关产品推荐
相关产品推荐

