使用flutter_blue在Android端扫描不到蓝牙设备,需要进行哪些调整?
代码逻辑修复
你当前的代码存在致命逻辑错误:扫描结果监听注册后立刻执行了cancel()操作,监听被直接销毁,永远无法收到扫描结果回调,且扫描是异步操作,你没有等待扫描执行完成就结束了流程。
修正后的参考代码如下:
FlutterBlue flutterInstance = FlutterBlue.instance; // 扫描监听订阅存为成员变量,方便管理 StreamSubscription? _scanSub; Future<void> _scanBT() async { print('触发蓝牙扫描'); // 先终止上一次未完成的扫描,避免冲突 await flutterInstance.stopScan(); // 先注册扫描结果监听,再启动扫描 _scanSub = flutterInstance.scanResults.listen((results) { for (var r in results) { print('扫描到设备:名称=${r.device.name}, MAC=${r.device.id}, 信号强度=${r.rssi}'); } }); // 启动扫描并等待扫描超时完成 await flutterInstance.startScan(timeout: const Duration(seconds: 8)); // 扫描结束后再取消监听 _scanSub?.cancel(); }
Android端权限配置调整
需要根据你的App目标安卓版本,在android/app/src/main/AndroidManifest.xml中添加对应权限:
- 安卓12(API 31)及以上版本添加如下权限:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 如果需要通过蓝牙推导设备物理位置,移除上面BLUETOOTH_SCAN的neverForLocation属性,并添加下面的位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- 安卓11(API 30)及以下版本添加如下权限:
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
运行时前置检查要求
蓝牙扫描执行前必须完成以下检查,全部通过后再执行扫描逻辑:
- 检查设备蓝牙开关是否已开启,未开启时要先触发系统弹窗申请开启蓝牙
- 动态申请上一步配置的所有权限,确认所有权限都被用户授权后再扫描,仅在清单文件声明权限无效
- 检查设备定位服务是否已开启,绝大多数安卓设备要求定位服务开启才能扫描到BLE蓝牙设备
其他排查点
- 确认你要扫描的是BLE低功耗蓝牙设备,flutter_blue不支持经典蓝牙设备扫描
- 不要频繁重复触发扫描,两次扫描间隔至少留2秒以上,避免系统蓝牙模块被占用
- flutter_blue官方已停止维护多年,如果以上配置都完成还是扫描失败,可以替换为社区维护的
flutter_blue_plus分支,API基本兼容
内容的提问来源于stack exchange,提问作者M.Pratheep
相关产品推荐
相关产品推荐

