Android端Bluetooth LE (BLE)扫描异常问题求助(2021年11月)
核心问题与修复方案
1. 权限分层适配逻辑错误
你配置的BLUETOOTH_SCAN权限仅适用于Android 12(API 31)及以上系统,而出故障的Android 9(API 28)、Android 11(API 30)设备走的是旧版权限规则,需要单独适配:
- Android 6.0~Android 11(API 23~30):BLE扫描必须同时满足三个条件:应用已获得
ACCESS_FINE_LOCATION权限、系统全局位置开关已开启、蓝牙已打开。很多开发者容易忽略系统全局位置开关的检查,仅确认应用权限就认为配置完成。 - Android 10(API 29)及以上如果要后台扫描:必须额外申请
ACCESS_BACKGROUND_LOCATION权限,且用户必须选择「始终允许位置权限」,选「仅使用期间允许」的话后台扫描会被系统直接拦截。
2. 权限标记冲突
你给BLUETOOTH_SCAN加了android:usesPermissionFlags="neverForLocation"标记,这个标记的作用是告诉系统你的BLE扫描不会用于定位,不需要申请位置权限,但你同时又配置了无版本限制的ACCESS_FINE_LOCATION、ACCESS_BACKGROUND_LOCATION权限,会导致系统权限判定逻辑冲突,在API 29~30的设备上会误判你的扫描用途,直接屏蔽扫描结果。
修复方案是给位置权限加上版本限制:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="30" />
如果你的应用不需要后台扫描,直接删除ACCESS_BACKGROUND_LOCATION权限即可,避免触发后台扫描的限制规则。
3. 扫描配置不符合系统限制
Android 9之后系统对BLE扫描增加了严格的限流和拦截规则,以下操作都会导致扫描无结果:
- 1分钟内反复调用启动/停止扫描接口超过5次,系统会拦截后续30秒的所有扫描请求
- 后台扫描时没有设置
ScanSettings.CALLBACK_TYPE_ALL_MATCHES,系统会默认屏蔽后台扫描结果 - 扫描模式设置为
SCAN_MODE_LOW_POWER时,系统会降低扫描频率,冷门BLE设备可能不会被扫描到
前台扫描推荐配置示例:
// 扫描过滤设置,为空的话扫描所有设备,也可以按服务UUID、设备名过滤 List<ScanFilter> filters = new ArrayList<>(); ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .build(); bluetoothLeScanner.startScan(filters, settings, scanCallback);
4. 额外检查项
确认你在扫描前主动检查蓝牙开关状态,Android 12以下需要BLUETOOTH_ADMIN权限请求用户开启蓝牙,不要默认假设蓝牙已打开。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

