import 'dart:async'; 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'; //连接状态回调 typedef ConnectStateCallBack = Function(DeviceConnectionState connectionState); class BlueManage { FlutterReactiveBle? _flutterReactiveBle; final List scanDevices = []; // 用来写入的服务id final Uuid _serviceIdConnect = Uuid.parse("fff0"); // 用来写入的服务id final Uuid _serviceIdWrite = Uuid.parse('0000FFF0-0000-1000-8000-00805F9B34FB'); // 用来订阅的特征id final Uuid _characteristicIdSubscription = Uuid.parse("fff1"); // 用来写入的特征id final Uuid _characteristicIdWrite = Uuid.parse("fff2"); // 监听发送事件 StreamSubscription? _sendStreamSubscription; // 监听蓝牙扫描的事件 StreamSubscription? _scanSubscription; // 监听蓝牙连接的事件 StreamSubscription? _currentConnectionStream; // 当前连接设备的名字 String connectDeviceName = ""; // 当前连接设备的mac地址 String connectDeviceMacAddress = ""; // 监听蓝牙连接状态 DeviceConnectionState? deviceConnectionState = DeviceConnectionState.disconnected; static BlueManage? _manager; BlueManage._init(); static BlueManage? shareManager() { _manager ??= BlueManage._init(); _manager!._initBlue(); return _manager; } factory BlueManage() => shareManager()!; BlueManage? get manager => shareManager(); void _initBlue(){ // print("蓝牙功能初始化了"); _flutterReactiveBle ??= FlutterReactiveBle(); _initSendStreamSubscription(); } void _initSendStreamSubscription() { _sendStreamSubscription ??= EventBusManager().eventBus!.on().listen((EventSendModel model) { if (model.sendChannel == DataChannel.ble) { // managerAppWriteData(model.data); _flutterReactiveBle!.statusStream.listen((status) { if (status == BleStatus.ready) { // 蓝牙已开启,可以进行蓝牙操作 writeCharacteristicWithResponse(model.data); }else{ Get.log("写入数据 蓝牙未开启,不能进行蓝牙操作"); } }); } }); } /// 开始扫描蓝牙设备 void startScan({List? idList}) { // List? list = _flutterReactiveBle!.getDiscoveredServices("deviceId").then((value)); _flutterReactiveBle!.statusStream.listen((status) { if (status == BleStatus.ready) { // 蓝牙已开启,可以进行蓝牙操作 scanDevices.clear(); _scanSubscription = _flutterReactiveBle!.scanForDevices(withServices:[]).listen((device) { // 判断名字为空的直接剔除 if (device.name.isEmpty) { return; } print("startScanDevice:$device"); if (((device.serviceUuids.isNotEmpty ? device.serviceUuids[0] : "").toString().contains("758824")) && (device.rssi >= -100)) { // 查询id相同的元素 final knownDeviceIndex = scanDevices.indexWhere((d) => d.id == device.id); // 不存在的时候返回-1 if (knownDeviceIndex >= 0) { scanDevices[knownDeviceIndex] = device; } else { scanDevices.add(device); } EventBusManager().eventBusFir(scanDevices); } }, onError: (Object e) { print('Device scan fails with error: $e'); }); }else{ Get.log("开始扫描 蓝牙未开启,不能进行蓝牙操作"); } }); } /// 调用发送数据 Future bludSendData(String deviceName, ConnectStateCallBack stateCallBack, {bool isAddEquipment = false}) async { _flutterReactiveBle!.statusStream.listen((status) { if (status == BleStatus.ready) { // 蓝牙已开启,可以进行蓝牙操作 if(deviceConnectionState != DeviceConnectionState.connected){ if(isAddEquipment == false){ // print("666666666"); startScan(); } _connect(deviceName, (state){ stateCallBack(deviceConnectionState!); }); }else{ // stopScan(); stateCallBack(deviceConnectionState!); } }else{ Get.log("调用发送数据 蓝牙未开启,不能进行蓝牙操作"); } }); } /// 连接监听状态 Future _connect(String deviceName, ConnectStateCallBack connectStateCallBack) async { connectDeviceName = deviceName; // 判断数组列表里面是否有这个设备 final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName); if (knownDeviceIndex >= 0) { // 存在的时候赋值 connectDeviceMacAddress = scanDevices[knownDeviceIndex].id; } else { // 不存在的时候返回-1 然后循环5秒 var index = 0; Completer? completer = Completer(); Timer.periodic(const Duration(seconds: 1), (timer) async { ///定时任务 // print("timer index0:$index"); if(index >= 9){ // 当超过5秒的时候取消定时任务 弹窗显示连接失败 connectDeviceMacAddress = ""; connectStateCallBack(DeviceConnectionState.disconnected); completer.complete(); stopScan(); timer.cancel(); // deviceConnectionState = DeviceConnectionState.disconnected; // print("timer index1:$index"); }else{ // 每秒判断数组列表里面是否有这个设备 final knownDeviceIndex = scanDevices.indexWhere((d) => d.name == deviceName); if (knownDeviceIndex >= 0) { // 存在的时候销毁定时器,赋值 connectDeviceMacAddress = scanDevices[knownDeviceIndex].id; stopScan(); completer.complete(); timer.cancel(); // print("timer index2:$index"); // var uuidStr = (scanDevices[knownDeviceIndex].serviceUuids.isNotEmpty ? scanDevices[knownDeviceIndex].serviceUuids[0] : "").toString(); // if(uuidStr[31] == "0"){ // // 未配对 表示这把锁已被强制初始化 处于可添加状态 不再连接 // EasyLoading.showToast("当前设备已被清除配对,请删除后重新添加", duration: 2000.milliseconds); // Future.delayed(2100.milliseconds); // connectStateCallBack(DeviceConnectionState.disconnected); // return; // } } else { // 不存在的时候返回-1 然后循环5秒 index++; print("index:$index"); } } }); // 等待Completer完成 await completer.future; } print("1 connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName"); // stopScan(); if (connectDeviceMacAddress.isEmpty) { return; } /// 用来判断是否返回了连接结果 还是放了一段时间后蓝牙主动断开的 var isReturnedConnectResults = false; _currentConnectionStream = _flutterReactiveBle!.connectToDevice(id: connectDeviceMacAddress, connectionTimeout: const Duration(seconds: 5)).listen((connectionStateUpdate) async { // 获取状态 deviceConnectionState = connectionStateUpdate.connectionState; stopScan(); print('2 deviceConnectionState:$deviceConnectionState connectionStateUpdate.connectionState:${connectionStateUpdate.connectionState}'); if (connectionStateUpdate.connectionState == DeviceConnectionState.connected) { isReturnedConnectResults = true; // 如果状态是连接的开始发现服务 try { _subScribeToCharacteristic(QualifiedCharacteristic(characteristicId: _characteristicIdSubscription, serviceId: _serviceIdConnect, deviceId: connectDeviceMacAddress)); print('Discovering services finished'); deviceConnectionState = connectionStateUpdate.connectionState; connectStateCallBack(deviceConnectionState!); } on Exception catch (e) { deviceConnectionState = DeviceConnectionState.disconnected; connectStateCallBack(deviceConnectionState!); print('Error occurred when discovering services: $e'); rethrow; } } else if (connectionStateUpdate.connectionState == DeviceConnectionState.disconnected) { // 如果状态是断开的 deviceConnectionState = connectionStateUpdate.connectionState; if(isReturnedConnectResults == false){ isReturnedConnectResults = true; // 如果是在连接中断开的 connectStateCallBack(deviceConnectionState!); } } print('ConnectionState for device $connectDeviceMacAddress : ${connectionStateUpdate.connectionState}'); }, onError: (Object e) { deviceConnectionState = DeviceConnectionState.disconnected; connectStateCallBack(deviceConnectionState!); print('Connecting to device $connectDeviceMacAddress resulted in error $e'); }); } // 听上报来的数据,参数来自前面扫描到的结果 var allData = []; // 保存上一次的数据,用来判断是否收到重复的数据 var lastTimeData = []; int? dataLen; _subScribeToCharacteristic(QualifiedCharacteristic characteristic) { _flutterReactiveBle!.subscribeToCharacteristic(characteristic).listen((data) { if(data == lastTimeData){ 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 = []; } } }, onError: (dynamic error) { EasyLoading.dismiss(); print("subscribeToCharacteristic error:$error"); }); } // 写入 Future writeCharacteristicWithResponse(List value) async { QualifiedCharacteristic characteristic = QualifiedCharacteristic(characteristicId: _characteristicIdWrite, serviceId: _serviceIdWrite, deviceId: connectDeviceMacAddress); int mtuLength = await _flutterReactiveBle!.requestMtu(deviceId: characteristic.deviceId, mtu: 250); print("mtuLength:$mtuLength"); try { List valueList = value; List subData = splitList(valueList, mtuLength); print('得到的分割数据:$subData'); for (int i = 0; i < subData.length; i++) { await _flutterReactiveBle! .writeCharacteristicWithResponse(characteristic, value: 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'); // ignore: avoid_print 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; } } // 停止扫描蓝牙设备 void stopScan() { // print("444444444"); if(_scanSubscription != null){ // print("555555555555"); _scanSubscription?.cancel(); _scanSubscription = null; } } // 断开连接 Future disconnect(String deviceMAC) async { try { connectDeviceMacAddress = ""; // if(_currentConnectionStream != null){ _currentConnectionStream?.cancel(); _currentConnectionStream = null; // } print('disconnecting to device: $connectDeviceName'); } on Exception catch (e, _) { print("Error disconnecting from a device: $e"); } finally { deviceConnectionState = DeviceConnectionState.disconnected; } } disposed() { _sendStreamSubscription?.cancel(); _currentConnectionStream?.cancel(); _scanSubscription?.cancel(); } }