Flutter中Movesense传感器固件更新时设备断连问题求助
解决Movesense固件更新时设备断开导致DFU失败的问题
问题核心是:Movesense进入DFU更新模式时会重启并切换到专门的DFU蓝牙广播,原有的BLE连接会被主动断开。你现在在设备刚连接时就直接触发DFU,此时设备还没完成模式切换断开,导致Nordic DFU无法正确连接到DFU模式下的设备。
直接给你可行的修改方案:
1. 增加DFU模式标记,区分断开类型
在当前逻辑作用域或BleDevice类中添加一个布尔标记,用来识别这次断开是进入DFU模式导致的,而非正常断开:
bool _isInitiatingDfu = false;
2. 修改固件更新方法,仅触发设备进入DFU模式
不要在startDeviceFirmwareUpdate里直接调用NordicDfu.startDfu,先只发送进入更新模式的请求,后续设备断开后再启动DFU:
@override Future<void> startDeviceFirmwareUpdate(String serial, int value) async { final Map<String, int> contract = {"NewState": value}; await MdsAsync.put(Mds.createRequestUri(serial, "/System/Mode"), jsonEncode(contract)); // 这里不再直接调用startDfu,等待设备断开后处理 }
3. 调整连接回调逻辑,在断开时启动DFU
修改connectMovesenseBleDeviceById的回调,当触发DFU模式后,在设备断开时启动Nordic DFU:
void connectMovesenseBleDeviceById({ required BleDevice device, required VoidCallback onConnect, required VoidCallback onDisconnect, }) { bleDataSource.connectMovesenseDeviceById( device.id, onConnnect: (serial) async { final metaData = await bleDataSource.getMovesenseSensorInfo(device.serial); final deviceAppData = await bleDataSource.getMovesenseSensorAppInfo(device.serial); device.metaData = metaData; device.appData = deviceAppData; // 标记即将进入DFU模式 _isInitiatingDfu = true; // 触发设备进入更新模式 bleDataSource.startDeviceFirmwareUpdate(device.serial, 12); // 保留原有正常连接逻辑 if (device.metaData!.isCompatible && device.appData!.isCompatible) { onConnect(); bleDeviceLocalDataSource.persistBleDevice(bleDeviceModel: device as BleDeviceModel); } if (!_connectedDevicesStreamController.isClosed) _connectedDevicesStreamController.add( device.copyWith(status: BleDeviceConnectionStatus.connected) as BleDeviceModel ); }, onDisconnect: () { // 如果是DFU模式触发的断开,启动DFU流程 if (_isInitiatingDfu) { _isInitiatingDfu = false; // 重置标记 // 启动Nordic DFU,DFU模式下设备蓝牙地址通常不变 NordicDfu().startDfu( device.id, 'assets/dfu.zip', fileInAsset: true, onDeviceDisconnecting: (string) => print('deviceAddress: $string'), onDeviceConnected: (address) => print("device is connected"), onDeviceConnecting: (address) => print("Device is connecting"), forceDfu: true, onError: (address, error, errorType, message) => print(" error $error, errorType: $errorType, message: $message"), onProgressChanged: (deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal) => print('deviceAddress: $deviceAddress, percent: $percent'), ); } else { // 正常断开逻辑 onDisconnect(); if (!_connectedDevicesStreamController.isClosed) _connectedDevicesStreamController.add( device.copyWith(status: BleDeviceConnectionStatus.disconnected) as BleDeviceModel ); } }, onError: () { throw BluetoothException('Error occured when pairing the device'); }, ); }
额外注意事项
- 确保你的Nordic DFU包版本兼容Movesense的DFU模式,
forceDfu: true必须开启,因为DFU模式下的设备没有正常的GATT服务。 - 极少数情况下,Movesense进入DFU模式后蓝牙地址可能会变化,如果出现连接失败,需要添加扫描逻辑,找到名称带"DFU"标识的设备,再用新地址启动DFU。
内容的提问来源于stack exchange,提问作者Aymen Ziouche
相关产品推荐
相关产品推荐

