import 'dart:async'; import 'dart:io'; import 'package:flutter_easyloading/flutter_easyloading.dart'; // import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:get/get.dart'; import 'io_tool/io_model.dart'; import 'io_tool/io_tool.dart'; import 'io_tool/manager_event_bus.dart'; import 'reciver_data.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; //连接状态回调 typedef ConnectStateCallBack = Function(BluetoothConnectionState connectionState); typedef ScanDevicesCallBack = Function(List); class BlueManage { final List scanDevices = []; // 用来写入的服务id final Guid _serviceIdConnect = Guid("fff0"); // 用来写入的服务id final Guid _serviceIdWrite = Guid('0000FFF0-0000-1000-8000-00805F9B34FB'); // 用来订阅的特征id final Guid _characteristicIdSubscription = Guid("fff1"); // 用来写入的特征id final Guid _characteristicIdWrite = Guid("fff2"); // 监听发送事件 StreamSubscription? _sendStreamSubscription; // 监听蓝牙扫描的事件 // StreamSubscription? _scanSubscription; // 监听蓝牙连接的事件 // StreamSubscription? _currentConnectionStream; // StreamSubscription>? _scanResultsSubscription; StreamSubscription? _connectionStateSubscription; StreamSubscription? _mtuSubscription; int? _mtuSize = 20; // 当前连接设备的名字 String connectDeviceName = ""; // 当前连接设备的mac地址 String connectDeviceMacAddress = ""; // 当前连接的设备 BluetoothDevice? bluetoothConnectDevice; // 当前扫描到结果要连接设备 ScanResult? scanResult; // 监听蓝牙连接状态 BluetoothConnectionState? bluetoothConnectionState = BluetoothConnectionState.disconnected; BluetoothAdapterState? _adapterState = BluetoothAdapterState.unknown; StreamSubscription? _adapterStateStateSubscription; static BlueManage? _manager; BlueManage._init(){ _initBlue(); } static BlueManage? shareManager() { _manager ??= BlueManage._init(); // _manager!._initBlue(); return _manager; } factory BlueManage() => shareManager()!; BlueManage? get manager => shareManager(); void _initBlue(){ print("蓝牙功能初始化监听"); _initSendStreamSubscription(); _initAdapterStateStateSubscription(); // _initListenscanResults(); // _initListenConnectionState(); } void _initGetMtuSubscription() { _mtuSubscription ??= bluetoothConnectDevice!.mtu.listen((value) { _mtuSize = value - 3; print('mtuSize:$_mtuSize'); }); } void _initAdapterStateStateSubscription() { _adapterStateStateSubscription ??= FlutterBluePlus.adapterState.listen((state) { _adapterState = state; }); } // void _initListenscanResults() { // var subscription = FlutterBluePlus.scanResults.listen((results) { // scanDevices.clear(); // for (var scanResult in results) { // // 判断名字为空的直接剔除 // // if (scanResult.device.advName.isEmpty) { // // return; // // } // print("scanResult.device.advName:${scanResult.device.advName}" // " scanResult.advertisementData.serviceUuids:${scanResult.advertisementData.serviceUuids}" // " rssi:${scanResult.rssi}"); // if (((scanResult.advertisementData.serviceUuids.isNotEmpty ? scanResult.advertisementData.serviceUuids[0] : "").toString().contains("758824")) && (scanResult.rssi >= -100)) { // // 查询id相同的元素 // final knownDeviceIndex = scanDevices.indexWhere((d) => d.advertisementData.advName == scanResult.advertisementData.advName); // // 不存在的时候返回-1 // if (knownDeviceIndex >= 0) { // scanDevices[knownDeviceIndex] = scanResult; // } else { // scanDevices.add(scanResult); // } // } // } // EventBusManager().eventBusFir(scanDevices); // // FlutterBluePlus.stopScan(); // }, onError: (e) { // print("Scan Error:$e", ); // }); // // FlutterBluePlus.cancelWhenScanComplete(subscription); // FlutterBluePlus.isScanning.listen((state) { // if (state) { // print('Scanning'); // } else { // print('Not scanning'); // } // }); // } void _initListenConnectionState() { _connectionStateSubscription?.cancel(); _connectionStateSubscription = null; _connectionStateSubscription = bluetoothConnectDevice!.connectionState.listen((state) async { bluetoothConnectionState = state; Get.log("蓝牙连接状态:$state"); }); } void _initSendStreamSubscription() { _sendStreamSubscription ??= EventBusManager().eventBus!.on().listen((EventSendModel model) { if (model.sendChannel == DataChannel.ble) { FlutterBluePlus.isSupported.then((isAvailable) async { if (isAvailable) { if (_adapterState == BluetoothAdapterState.on) { // 蓝牙已开启,可以进行蓝牙操作 writeCharacteristicWithResponse(model.data); } else { try { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } } catch (e) { Get.log("Error Turning On:"); } } } else { Get.log("写入数据 蓝牙不可用,不能进行蓝牙操作"); } }); } }); } /// 开始扫描蓝牙设备 Future startScan(int timeout, ScanDevicesCallBack scanDevicesCallBack, {List? idList}) async { FlutterBluePlus.isSupported.then((isAvailable) async { if (isAvailable) { if (_adapterState == BluetoothAdapterState.on) { try { FlutterBluePlus.startScan(timeout: Duration(seconds: timeout)); var subscription = FlutterBluePlus.scanResults.listen((results) { scanDevices.clear(); for (var scanResult in results) { // 判断名字为空的直接剔除 // if (scanResult.device.advName.isEmpty) { // return; // } Get.log("scanResult.device.advName:${scanResult.device.advName}" " scanResult.advertisementData.serviceUuids:${scanResult.advertisementData.serviceUuids}" " rssi:${scanResult.rssi}"); if (((scanResult.advertisementData.serviceUuids.isNotEmpty ? scanResult.advertisementData.serviceUuids[0] : "").toString().contains("758824")) && (scanResult.rssi >= -100)) { // 查询id相同的元素 final knownDeviceIndex = scanDevices.indexWhere((d) => d.advertisementData.advName == scanResult.advertisementData.advName); // 不存在的时候返回-1 if (knownDeviceIndex >= 0) { scanDevices[knownDeviceIndex] = scanResult; } else { scanDevices.add(scanResult); } } } scanDevicesCallBack(scanDevices); // EventBusManager().eventBusFir(scanDevices); // FlutterBluePlus.stopScan(); }, onError: (e) { print("Scan Error:$e", ); }); FlutterBluePlus.cancelWhenScanComplete(subscription); } catch (e) { Get.log("扫描失败"); } } else { try { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } } catch (e) { Get.log("Error Turning On:"); } }; } else { Get.log("开始扫描 蓝牙不可用,不能进行蓝牙操作"); } }); } /// 调用发送数据 Future bludSendData(String deviceName, ConnectStateCallBack stateCallBack, {bool isAddEquipment = false}) async { FlutterBluePlus.isSupported.then((isAvailable) async { if (isAvailable) { if (_adapterState == BluetoothAdapterState.on) { // 蓝牙已开启,可以进行蓝牙操作 if(bluetoothConnectionState != BluetoothConnectionState.connected){ _connect(deviceName, (state){ // if(bluetoothConnectionState != BluetoothConnectionState.connected){ // stateCallBack(bluetoothConnectionState!); // }else{ // stateCallBack(bluetoothConnectionState!); // } stateCallBack(bluetoothConnectionState!); }, isAddEquipment: isAddEquipment); }else{ stateCallBack(bluetoothConnectionState!); } } else { try { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } } catch (e) { Get.log("Error Turning On:"); } }; } else { Get.log("开始扫描 蓝牙不可用,不能进行蓝牙操作"); } }); } /// 连接 Future _connect(String deviceName, ConnectStateCallBack connectStateCallBack, {bool isAddEquipment = false}) async { connectDeviceName = deviceName; List devicesList = scanDevices; if(isAddEquipment == false){ startScan(10, (List scanDevices){ print("扫描到的设备:$scanDevices"); devicesList = scanDevices; _connectDevice(devicesList, deviceName, connectStateCallBack, isAddEquipment: isAddEquipment); }); }else{ _connectDevice(devicesList, deviceName, connectStateCallBack, isAddEquipment: isAddEquipment); } } Future _connectDevice( List devicesList, String deviceName, ConnectStateCallBack connectStateCallBack, {bool isAddEquipment = false}) async { // 判断数组列表里面是否有这个设备 print("devicesList:$devicesList"); final knownDeviceIndex = devicesList.indexWhere((d) => d.advertisementData.advName == deviceName); if (knownDeviceIndex >= 0) { // 存在的时候赋值 connectDeviceMacAddress = devicesList[knownDeviceIndex].advertisementData.advName; bluetoothConnectDevice = devicesList[knownDeviceIndex].device; print('bluetoothConnectDevice: $bluetoothConnectDevice'); scanResult = devicesList[knownDeviceIndex]; _initGetMtuSubscription(); _initListenConnectionState(); } print("1 connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName"); // stopScan(); if (connectDeviceMacAddress.isEmpty) { // connectStateCallBack(BluetoothConnectionState.disconnected!); return; } Get.log("调用了停止扫描的方法"); await stopScan(); if ((scanResult!.advertisementData.serviceUuids[0].toString()[31] == "0") && isAddEquipment == false) { connectStateCallBack(BluetoothConnectionState.disconnected!); EasyLoading.showToast("该锁已被重置", duration: 2000.milliseconds); return; } // 重连三次 int maxAttempts = 3; int attempt = 0; while (attempt < maxAttempts) { try { await bluetoothConnectDevice!.connect(timeout: 5.seconds); break; // If the connection is successful, break the loop } catch (e) { Get.log('Failed to connect: $e'); attempt++; // Increase the attempt count if (attempt < maxAttempts) { Get.log('Retrying connection...'); } } } if (attempt >= maxAttempts) { Get.log('Failed to connect after $maxAttempts attempts.'); connectStateCallBack(BluetoothConnectionState.disconnected!); } // await bluetoothConnectDevice!.connect(); print("5555555:回调状态:$bluetoothConnectionState"); if (bluetoothConnectionState == BluetoothConnectionState.connected) { try { bluetoothConnectDevice!.discoverServices().then((services) { print("333333333"); for (BluetoothService service in services) { // print("11111service.remoteId:${service.remoteId}" // " service.uuid:${service.uuid}" // " service.characteristics:${service.characteristics}" // " service.includedServices:${service.includedServices}"); if(service.uuid == _serviceIdConnect){ for (BluetoothCharacteristic characteristic in service.characteristics) { // print("22222characteristic.remoteId:${characteristic.remoteId}" // " characteristic.uuid:${characteristic.uuid}" // " characteristic.secondaryServiceUuid:${characteristic.secondaryServiceUuid}" // " characteristic.characteristicUuid:${characteristic.characteristicUuid}"); if (characteristic.characteristicUuid == _characteristicIdSubscription) { print("44444444"); _subScribeToCharacteristic(characteristic); print('Discovering services finished'); bluetoothConnectionState = BluetoothConnectionState.connected; connectStateCallBack(bluetoothConnectionState!); } } } } }); } on Exception catch (e) { bluetoothConnectionState = BluetoothConnectionState.disconnected; Get.log("5555 回调状态:$bluetoothConnectionState"); connectStateCallBack(bluetoothConnectionState!); print('Error occurred when discovering services: $e'); rethrow; } } } // 听上报来的数据,参数来自前面扫描到的结果 var allData = []; // 保存上一次的数据,用来判断是否收到重复的数据 var lastTimeData = []; int? dataLen; _subScribeToCharacteristic(BluetoothCharacteristic characteristic) async { final subscription = characteristic.onValueReceived.listen((data) { print("启动对特性的通知。当特性的值发生变化时,设备会发送一个通知"); print("订阅获取的数据:$data"); if(data == lastTimeData || data.isEmpty){ return; }else{ lastTimeData = data; } // code to handle incoming data // print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data"); if ((data[0] == 0xEF) && (data[1] == 0x01) && (data[2] == 0xEE) && (data[3] == 0x02)) { // 当包有头时 // 判断是否需要分包 dataLen = data[8] * 256 + data[9]; // 高16位用来指示后面数据块内容的长度 // print("dataLen1111:$dataLen getDataLength:${data.length}"); if (dataLen! + 12 > data.length) { // 当前包的长度小于实际的包时 分包添加 不解析 allData.addAll(data); } else { // 当前包的长度小于实际的包时 不分包 解析 allData.addAll(data); // print("dataLen2222:$dataLen getDataLength:${data.length}"); CommandReciverManager.appDataReceive(allData); // 发送完解析初始化数组 allData = []; } } else { // 当包没有头时 是分包的包 直接添加 allData.addAll(data); // var len = allData[8] * 256 + allData[9]; // print("dataLen3333:$dataLen"); if ((dataLen! + 14) <= allData.length) { // print("44444数据被解析了"); // 当长度小于等于当前包的数据时 直接解析数据 CommandReciverManager.appDataReceive(allData); // 发送完解析初始化数组 allData = []; } } }); // cleanup: cancel subscription when disconnected bluetoothConnectDevice!.cancelWhenDisconnected(subscription); // enable notifications await characteristic.setNotifyValue(true); // characteristic.setNotifyValue(true).then((_) { // print("启动对特性的通知。当特性的值发生变化时,设备会发送一个通知"); // characteristic.lastValueStream.listen((data) { // print("订阅获取的数据:$data"); // // do something with new value // if(data == lastTimeData || data.isEmpty){ // return; // }else{ // lastTimeData = data; // } // // code to handle incoming data // // print("subscribeToCharacteristic: deviceId = ${characteristic.deviceId} characteristicId =${characteristic.characteristicId}---上报来的数据data = $data"); // if ((data[0] == 0xEF) && (data[1] == 0x01) && (data[2] == 0xEE) && (data[3] == 0x02)) { // // 当包有头时 // // 判断是否需要分包 // dataLen = data[8] * 256 + data[9]; // 高16位用来指示后面数据块内容的长度 // // print("dataLen1111:$dataLen getDataLength:${data.length}"); // if (dataLen! + 12 > data.length) { // // 当前包的长度小于实际的包时 分包添加 不解析 // allData.addAll(data); // } else { // // 当前包的长度小于实际的包时 不分包 解析 // allData.addAll(data); // // print("dataLen2222:$dataLen getDataLength:${data.length}"); // CommandReciverManager.appDataReceive(allData); // // 发送完解析初始化数组 // allData = []; // } // } else { // // 当包没有头时 是分包的包 直接添加 // allData.addAll(data); // // var len = allData[8] * 256 + allData[9]; // // print("dataLen3333:$dataLen"); // if ((dataLen! + 14) <= allData.length) { // // print("44444数据被解析了"); // // 当长度小于等于当前包的数据时 直接解析数据 // CommandReciverManager.appDataReceive(allData); // // 发送完解析初始化数组 // allData = []; // } // } // }); // }); } // 写入 Future writeCharacteristicWithResponse(List value) async { bluetoothConnectDevice!.discoverServices().then((services) async { for (BluetoothService service in services) { // print("33333 service.remoteId:${service.remoteId}" // " service.uuid:${service.uuid}\n\n" // " service.characteristics:${service.characteristics}\n\n" // " service.includedServices:${service.includedServices}"); if (service.uuid == _serviceIdConnect) { for (BluetoothCharacteristic characteristic in service .characteristics) { // print("44444 characteristic.remoteId:${characteristic.remoteId}" // " characteristic.uuid:${characteristic.uuid}\n\n" // " characteristic.secondaryServiceUuid:${characteristic // .secondaryServiceUuid}\n\n" // " characteristic.characteristicUuid:${characteristic // .characteristicUuid}"); if (characteristic.characteristicUuid == _characteristicIdWrite) { try { List valueList = value; List subData = splitList(valueList, _mtuSize!); print( 'writeCharacteristicWithResponse 得到的分割数据:$subData'); for (int i = 0; i < subData.length; i++) { await characteristic.write(subData[i]).then((value) async { await Future.delayed(const Duration(milliseconds: 1)).then(( value) async { print('分包发送成功了'); }); }); } } on Exception catch (e, s) { print('Error occurred when writing: $e'); print(s); rethrow; } } } } } }); // List services = await bluetoothConnectDevice!.discoverServices(); // BluetoothCharacteristic characteristic = services // .firstWhere((service) => service.uuid == _serviceIdWrite) // .characteristics // .firstWhere((char) => char.uuid == _characteristicIdWrite); // try { // List valueList = value; // List subData = splitList(valueList, _mtuSize!); // print('writeCharacteristicWithResponse 得到的分割数据:$subData'); // // for (int i = 0; i < subData.length; i++) { // await characteristic.write(subData[i]).then((value) async { // await Future.delayed(const Duration(milliseconds: 1)).then((value) async { // print('分包发送成功了'); // }); // }); // } // } on Exception catch (e, s) { // print('Error occurred when writing: $e'); // print(s); // rethrow; // } } // 读取 // Future> _readCharacteristic(QualifiedCharacteristic characteristic) async { // try { // final result = // await _flutterReactiveBle!.readCharacteristic(characteristic); // print("readListresult$result"); // return result; // } on Exception catch (e, s) { // print( // 'Error occurred when reading ${characteristic.characteristicId} : $e', // ); // rethrow; // } // } // Future writeCharacteristicWithoutResponse( // QualifiedCharacteristic characteristic, List value) async { // try { // await _flutterReactiveBle! // .writeCharacteristicWithoutResponse(characteristic, value: value); // } on Exception catch (e, s) { // // ignore: avoid_print // print(s); // rethrow; // } // } // 停止扫描蓝牙设备 Future stopScan() async { try { await FlutterBluePlus.stopScan(); } catch (e) { Get.log("停止扫描失败"); } } // 断开连接 Future disconnect() async { try { connectDeviceMacAddress = ""; await bluetoothConnectDevice!.disconnect(); Get.log("断开连接成功"); } on Exception catch (e, _) { print("Error disconnecting from a device: $e"); } finally { bluetoothConnectionState = BluetoothConnectionState.disconnected; } } disposed() { _sendStreamSubscription?.cancel(); _mtuSubscription!.cancel(); // _scanResultsSubscription!.cancel(); _adapterStateStateSubscription!.cancel(); _connectionStateSubscription!.cancel(); } }