寻求Flutter实现BLE设备文件下载及数据交互响应代码方案
Flutter BLE设备文件下载及数据响应处理方案
依赖配置
在pubspec.yaml中添加BLE操作依赖:
dependencies: flutter_blue_plus: ^1.13.18 path_provider: ^2.1.1
核心实现代码
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; class BLEDataDownloader { BluetoothDevice? _connectedDevice; BluetoothCharacteristic? _txChar; // 发送数据特征 BluetoothCharacteristic? _rxChar; // 接收数据特征 File? _targetFile; List<int> _fileBuffer = []; bool _isDownloading = false; // 扫描并连接指定设备 Future<void> connectDevice(String targetDeviceId) async { final flutterBlue = FlutterBluePlus.instance; // 开始扫描 flutterBlue.startScan(timeout: const Duration(seconds: 5)); flutterBlue.scanResults.listen((results) { for (final result in results) { if (result.device.id.toString() == targetDeviceId) { flutterBlue.stopScan(); _establishConnection(result.device); break; } } }); } // 建立设备连接并绑定特征 Future<void> _establishConnection(BluetoothDevice device) async { await device.connect(); _connectedDevice = device; // 发现设备服务 final services = await device.discoverServices(); for (final service in services) { // 替换为你的BLE服务UUID if (service.uuid.toString() == "0000ffe0-0000-1000-8000-00805f9b34fb") { for (final char in service.characteristics) { // 替换为你的BLE通信特征UUID if (char.uuid.toString() == "0000ffe1-0000-1000-8000-00805f9b34fb") { if (char.properties.write) _txChar = char; if (char.properties.notify) { _rxChar = char; await char.setNotifyValue(true); // 监听设备返回数据 char.value.listen(_parseIncomingData); } } } } } } // 解析并分类处理设备返回数据 void _parseIncomingData(List<int> rawData) { // 根据设备协议解析帧类型(示例:第2字节为帧类型标识) final frameType = rawData[1]; switch (frameType) { case 0x01: // 文件下载确认帧 _initFileDownload(); break; case 0x02: // 文件数据帧 _appendFileData(rawData); break; case 0x03: // 下载完成帧 _completeFileDownload(); break; default: print("未知帧类型: $frameType"); } } // 初始化文件下载 Future<void> _initFileDownload() async { final docDir = await getApplicationDocumentsDirectory(); _targetFile = File("${docDir.path}/recorder_data.bin"); _fileBuffer.clear(); _isDownloading = true; // 向设备发送确认响应 await _txChar?.write([0x01, 0x00]); } // 处理文件数据块 void _appendFileData(List<int> dataFrame) { if (!_isDownloading) return; // 根据协议提取有效数据段(示例:从第4字节开始,长度为第3字节值) final dataLength = dataFrame[2]; final fileChunk = dataFrame.sublist(4, 4 + dataLength); _fileBuffer.addAll(fileChunk); // 向设备发送数据接收确认 _txChar?.write([0x02, 0x00]); } // 完成文件下载 Future<void> _completeFileDownload() async { if (_targetFile != null && _fileBuffer.isNotEmpty) { await _targetFile?.writeAsBytes(_fileBuffer); print("文件已保存至: ${_targetFile?.path}"); } _isDownloading = false; _fileBuffer.clear(); // 向设备发送下载完成确认 await _txChar?.write([0x03, 0x00]); } // 向设备发送文件下载请求 Future<void> requestFileDownload() async { // 替换为设备协议规定的下载请求帧 await _txChar?.write([0x00, 0x01, 0x00, 0x00]); } // 断开连接 Future<void> disconnect() async { await _connectedDevice?.disconnect(); _connectedDevice = null; _txChar = null; _rxChar = null; } }
权限配置
Android(AndroidManifest.xml)
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
iOS(Info.plist)
<key>NSBluetoothAlwaysUsageDescription</key> <string>需要蓝牙连接行驶记录仪下载数据</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>需要蓝牙连接行驶记录仪下载数据</string>
关键说明
- 替换代码中的服务UUID和特征UUID为你的BLE设备实际值
- 根据设备通信协议调整
_parseIncomingData中的帧解析逻辑(帧头位置、类型标识、数据段提取规则等) - 命令帧内容需与现有Java实现保持一致,确保设备能识别请求
内容的提问来源于stack exchange,提问作者Abdurrahman yeşilyurt
相关产品推荐
相关产品推荐

