Flutter应用无法在后台运行WiFi与蓝牙扫描求助
解决方案:Flutter后台持续扫描WiFi/蓝牙设备
一、蓝牙扫描替换为flutter_reactive_ble
flutter_blue在后台扫描的兼容性较差,flutter_reactive_ble对后台扫描的支持更完善,无需复杂原生修改:
配置权限
在android/app/src/main/AndroidManifest.xml中添加以下权限:<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- Android 12+ 需添加 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />后台扫描代码示例
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; final _ble = FlutterReactiveBle(); StreamSubscription? _scanSubscription; void startBleBackgroundScan() { _scanSubscription = _ble.scanForDevices( withServices: [], // 留空扫描所有蓝牙设备 scanMode: ScanMode.lowLatency, // 高频扫描用lowLatency,低功耗用lowPower ).listen((device) { // 获取Mac地址(device.id)和RSSI值 print("蓝牙设备MAC: ${device.id}, RSSI: ${device.rssi}"); }); } // 停止扫描 void stopBleScan() => _scanSubscription?.cancel();
二、WiFi扫描结合前台服务实现后台执行
Android 10+ 对后台WiFi扫描有严格限制,必须通过前台服务才能持续执行高频扫描,推荐结合flutter_foreground_task和wifi_scan:
配置权限与前台服务
在AndroidManifest.xml中补充权限:<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />前台服务中执行WiFi扫描
import 'package:flutter_foreground_task/flutter_foreground_task.dart'; import 'package:wifi_scan/wifi_scan.dart'; // 初始化前台服务 void initForegroundTask() { FlutterForegroundTask.init( androidNotificationOptions: AndroidNotificationOptions( channelId: 'location_scan_channel', channelName: '室内定位扫描', channelDescription: '后台持续扫描WiFi与蓝牙设备', iconData: NotificationIconData( resType: ResourceType.mipmap, resPrefix: ResourcePrefix.ic, name: 'launcher', ), ), iosNotificationOptions: const IOSNotificationOptions(), ); } // 启动后台扫描任务 Future<void> startBackgroundScanTask() async { await FlutterForegroundTask.startService( notificationTitle: '室内定位扫描中', notificationText: '后台持续获取设备数据', callback: scanTaskCallback, ); } // 扫描任务回调(后台执行) void scanTaskCallback() { // 每6秒执行一次扫描 Timer.periodic(const Duration(seconds: 6), (timer) async { // 检查WiFi扫描权限 if (await WifiScan.instance.hasPermission()) { final scannedResults = await WifiScan.instance.getScannedResults(); for (final result in scannedResults) { // 获取WiFi MAC(bssid)和RSSI值 print("WiFi设备MAC: ${result.bssid}, RSSI: ${result.rssi}"); } } // 这里可以同时执行蓝牙扫描(调用上面的startBleBackgroundScan) }); }
三、关于backgroundMode: true的插件说明
不存在仅靠backgroundMode: true参数就能绕过系统限制实现后台扫描的插件——Android/iOS对后台定位、蓝牙/WiFi扫描有严格的系统级限制,必须依赖权限申请+前台服务才能实现高频扫描需求。上述方案中flutter_reactive_ble和flutter_foreground_task的组合已经能满足你的需求,无需寻找特定参数的插件。
四、平台额外注意事项
- iOS限制:iOS后台蓝牙扫描需在
Info.plist添加NSBluetoothAlwaysUsageDescription,并开启后台模式"Uses Bluetooth LE accessories";WiFi后台扫描限制极严,无法实现每6秒一次的高频扫描,仅能在特定场景下触发。 - 权限动态申请:必须在代码中动态申请位置、蓝牙、后台位置等权限,否则扫描功能会被系统禁用。
内容的提问来源于stack exchange,提问作者Baran
相关产品推荐
相关产品推荐

