如何让Flutter应用后台运行并监听蓝牙设备信号?
Flutter 后台持续监听蓝牙设备解决方案
核心问题说明
你用的flutter_background这类包仅能维持后台进程存活,但蓝牙监听需要系统级的蓝牙权限与平台专属实现配合,单纯保活无法触发蓝牙数据回调,必须针对Android和iOS的后台机制分别处理。
Android 平台实现步骤
1. 配置必要权限
在android/app/src/main/AndroidManifest.xml中添加权限:
<!-- 蓝牙基础权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <!-- 后台运行权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
2. 前台服务绑定蓝牙监听
Android 12+对后台蓝牙限制严格,必须通过前台服务才能持续获取数据,推荐用维护活跃的flutter_blue_plus包实现:
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:flutter_background/flutter_background.dart'; import 'package:permission_handler/permission_handler.dart'; Future<void> initBluetoothBackgroundListener() async { // 初始化后台前台服务配置 final androidConfig = FlutterBackgroundAndroidConfig( notificationTitle: "蓝牙监听中", notificationText: "正在接收设备数据", notificationIcon: AndroidResource(name: "@mipmap/ic_launcher"), notificationImportance: AndroidNotificationImportance.Default, ); await FlutterBackground.initialize(androidConfig: androidConfig); await FlutterBackground.enableBackgroundExecution(); // 请求忽略电池优化(必做,否则系统会杀进程) final batteryStatus = await Permission.ignoreBatteryOptimizations.request(); if (batteryStatus.isDenied) openAppSettings(); // 扫描并连接目标设备,监听特征值变化 FlutterBluePlus.scanResults.listen((results) { for (var result in results) { if (result.device.name == "你的嵌入式设备名称") { result.device.connect(autoConnect: true).then((_) { result.device.discoverServices().then((services) { for (var service in services) { for (var characteristic in service.characteristics) { // 开启特征值通知 characteristic.setNotifyValue(true); // 后台会触发此回调,处理设备数据 characteristic.value.listen((value) => _handleDeviceSignal(value)); } } }); }); FlutterBluePlus.stopScan(); } } }); await FlutterBluePlus.startScan(); } void _handleDeviceSignal(List<int> data) { // 这里写你需要触发的业务逻辑 }
iOS 平台实现步骤
iOS后台蓝牙依赖CoreBluetooth的后台模式配置,系统会在蓝牙设备发送通知时唤醒应用:
1. 配置后台模式与权限
在ios/Runner/Info.plist中添加:
<key>UIBackgroundModes</key> <array> <string>bluetooth-central</string> <!-- 作为中心设备监听蓝牙 --> </array> <key>NSBluetoothAlwaysUsageDescription</key> <string>需要蓝牙权限以持续接收设备数据</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>需要蓝牙权限以连接嵌入式设备</string>
2. 蓝牙监听实现
用flutter_blue_plus配置自动重连与通知监听,后台会自动触发回调:
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; Future<void> initIOSBluetoothListener() async { // 扫描并连接目标设备 FlutterBluePlus.scanResults.listen((results) { for (var result in results) { if (result.device.name == "你的嵌入式设备名称") { // autoConnect: true 确保后台断开后自动重连 result.device.connect(autoConnect: true).then((_) { result.device.discoverServices().then((services) { for (var service in services) { for (var char in service.characteristics) { if (char.properties.notify) { char.setNotifyValue(true); // 后台收到设备信号时触发此回调 char.value.listen((value) => _handleDeviceSignal(value)); } } } }); }); FlutterBluePlus.stopScan(); } } }); await FlutterBluePlus.startScan(); } void _handleDeviceSignal(List<int> data) { // 你的业务逻辑 }
iOS 注意事项
- 仅当蓝牙设备的特征值配置了通知属性时,后台才能收到更新
- 后台唤醒后不能执行耗时操作,否则会被系统终止
替代方案
如果Flutter生态包无法满足需求,可考虑:
- 原生混合开发:Android用
ForegroundService+BluetoothGatt,iOS用CoreBluetooth,通过MethodChannel与Flutter交互 - React Native:社区
react-native-ble-plx包对后台蓝牙监听的支持更成熟
内容的提问来源于stack exchange,提问作者Hrishabh Nayal
相关产品推荐
相关产品推荐

