Flutter使用flutter_blue_plus:蓝牙自动重连后如何获取设备对象
Flutter Blue Plus 蓝牙自动重连后重新获取设备对象的优化方案
你的定时轮询方案虽然能解决问题,但存在资源消耗、检测延迟等问题,这里提供更高效的优化思路:
核心优化方向:用事件监听替代定时轮询
利用flutter_blue_plus自带的蓝牙状态流,在连接状态发生变化时自动触发设备匹配,避免无意义的周期性查询。
1. 监听设备连接状态变更
直接注册全局连接状态流监听,当目标设备重新连接时,自动获取并更新设备对象:
// 初始化时注册监听逻辑 _flutterBlue.onConnectionStateChanged.listen((device, state) { // 先判断是否是目标设备 bool isTargetDevice = device.name == _vehicleInfo!.imei || device.name == '000000000000000'; if (!isTargetDevice) return; if (state == BluetoothConnectionState.connected) { _device = device; _bluetoothIsConnected = true; // 这里可以直接执行重连后的业务逻辑,比如重新订阅特征值 } else if (state == BluetoothConnectionState.disconnected) { _bluetoothIsConnected = false; // 标记设备断开,等待系统自动重连 } });
2. 缓存设备ID提升匹配准确性
设备名称可能存在重复或变更的情况,首次连接成功后缓存设备的唯一ID,后续匹配时优先用ID判断,避免误匹配:
String? _targetDeviceId; // 首次连接成功时缓存设备唯一ID void _deviceConnect(bool isFirstConnect) async { // ... 你的连接逻辑 if (isFirstConnect && _device != null) { _targetDeviceId = _device!.id.id; } } // 统一的设备匹配方法 void _matchTargetDevice(List<BluetoothDevice> devices) { for (var device in devices) { bool isMatch = device.id.id == _targetDeviceId || device.name == _vehicleInfo!.imei || device.name == '000000000000000'; if (isMatch) { _device = device; _bluetoothIsConnected = true; break; } } }
3. 结合蓝牙开关状态监听
如果手机蓝牙被关闭后重新开启,主动触发一次已连接设备的匹配操作:
_flutterBlue.state.listen((bluetoothState) { if (bluetoothState == BluetoothState.on) { // 蓝牙开启后,主动获取已连接设备并匹配目标设备 _getConnectedDevicesAndMatch(); } }); Future<void> _getConnectedDevicesAndMatch() async { List<BluetoothDevice> devices = await _flutterBlue.connectedDevices; _matchTargetDevice(devices); }
为什么不推荐定时轮询?
- 持续轮询会消耗CPU资源,后台运行时可能被系统限制甚至杀死进程
- 存在检测延迟,比如重连发生在两次轮询之间,需要等待最长2秒才能发现
- 逻辑冗余,框架本身提供了精准的事件监听机制,没必要自己实现轮询逻辑
内容的提问来源于stack exchange,提问作者Kelvin
相关产品推荐
相关产品推荐

