import 'dart:async'; import 'dart:io'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:get/get.dart'; import 'package:star_lock/app_settings/app_settings.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() { FlutterBluePlus.setLogLevel(LogLevel.error, color: true); _initSendStreamSubscription(); _initAdapterStateStateSubscription(); // _initListenscanResults(); // _initListenConnectionState(); } void _initGetMtuSubscription() { _mtuSubscription ??= bluetoothConnectDevice!.mtu.listen((value) { _mtuSize = value - 3; AppLog.log('_mtuSizeValue:$value 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; // // } // AppLog.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); // } // } // } // EventBusManager().eventBusFir(scanDevices); // // FlutterBluePlus.stopScan(); // }, onError: (e) { // AppLog.log("Scan Error:$e", ); // }); // // FlutterBluePlus.cancelWhenScanComplete(subscription); // FlutterBluePlus.isScanning.listen((state) { // if (state) { // prAppLog.logint('Scanning'); // } else { // AppLog.log('Not scanning'); // } // }); // } void _initListenConnectionState() { _connectionStateSubscription?.cancel(); _connectionStateSubscription = null; _connectionStateSubscription = bluetoothConnectDevice!.connectionState.listen((state) async { bluetoothConnectionState = state; // AppLog.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 {} catch (e) { AppLog.log("蓝牙打开失败"); } } } else { AppLog.log("写入数据 蓝牙不可用,不能进行蓝牙操作"); } }); } }); } /// 开始指定设备名称的扫描蓝牙设备 Future startScanSingle(String deviceName, int timeout, ScanDevicesCallBack scanDevicesCallBack) async { FlutterBluePlus.isSupported.then((isAvailable) async { if (isAvailable) { if (_adapterState == BluetoothAdapterState.on) { try { FlutterBluePlus.startScan(timeout: Duration(seconds: timeout)); Completer completer = Completer(); var subscription = FlutterBluePlus.scanResults.listen((results) { // AppLog.log("startScanSingle扫描到的设备:$results"); bool isExit = results.any((element) => (element.device.platformName == deviceName) || (element.advertisementData.advName == deviceName)); if (isExit) { for (var scanResult in results) { if (((scanResult.advertisementData.serviceUuids.isNotEmpty ? scanResult.advertisementData.serviceUuids[0] : "") .toString() .contains("758824")) && (scanResult.rssi >= -100)) { // 查询id相同的元素 final knownDeviceIndex = scanDevices.indexWhere((d) => (d.device.platformName == scanResult.device.platformName) || (d.advertisementData.advName == scanResult.advertisementData.advName)); // 不存在的时候返回-1 if (knownDeviceIndex >= 0) { scanDevices[knownDeviceIndex] = scanResult; } else { scanDevices.add(scanResult); } } } completer.complete(); } }, onError: (e) { AppLog.log( "扫描失败:$e", ); }); FlutterBluePlus.cancelWhenScanComplete(subscription); await completer.future; scanDevicesCallBack(scanDevices); subscription.cancel(); } catch (e) { AppLog.log("扫描失败"); } } else { try { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } } catch (e) { AppLog.log("蓝牙打开失败"); } } } else { AppLog.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; // } // AppLog.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.device.platformName == scanResult.device.platformName) || (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) { AppLog.log( "扫描失败:$e", ); }); FlutterBluePlus.cancelWhenScanComplete(subscription); } catch (e) { AppLog.log("扫描失败"); } } else { try { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } } catch (e) { AppLog.log("蓝牙打开失败"); } } } else { AppLog.log("开始扫描 蓝牙不可用,不能进行蓝牙操作"); } }); } /// 调用发送数据 List senderData, 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) { stateCallBack(bluetoothConnectionState!); }, isAddEquipment: isAddEquipment); } else { stateCallBack(bluetoothConnectionState!); } } else { try { stateCallBack(BluetoothConnectionState.disconnected); openBlue(); } catch (e) { AppLog.log("蓝牙打开失败"); } } } else { AppLog.log("开始扫描 蓝牙不可用,不能进行蓝牙操作"); } }); } /// 连接 Future _connect( String deviceName, ConnectStateCallBack connectStateCallBack, {bool isAddEquipment = false}) async { connectDeviceName = deviceName; List devicesList = scanDevices; if (isAddEquipment == false) { //取消缓存直接使用,存在配对场景设备信息会更变 startScan(10, (List 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 { // 判断数组列表里面是否有这个设备 // AppLog.log("devicesList:$devicesList"); final knownDeviceIndex = devicesList.indexWhere((d) => (d.device.platformName == deviceName) || (d.advertisementData.advName == deviceName)); if (knownDeviceIndex >= 0) { // 存在的时候赋值 connectDeviceMacAddress = devicesList[knownDeviceIndex].advertisementData.advName.isNotEmpty ? devicesList[knownDeviceIndex].advertisementData.advName : devicesList[knownDeviceIndex].device.platformName; bluetoothConnectDevice = devicesList[knownDeviceIndex].device; // AppLog.log('bluetoothConnectDevice: $bluetoothConnectDevice'); scanResult = devicesList[knownDeviceIndex]; _initGetMtuSubscription(); _initListenConnectionState(); } // AppLog.log("1 connectDeviceId:$connectDeviceMacAddress connectDeviceName:$connectDeviceName"); // stopScan(); if (connectDeviceMacAddress.isEmpty) { // connectStateCallBack(BluetoothConnectionState.disconnected!); return; } // AppLog.log("调用了停止扫描的方法"); await stopScan(); if ((scanResult!.advertisementData.serviceUuids[0].toString()[31] == "0") && isAddEquipment == false) { connectStateCallBack(BluetoothConnectionState.disconnected); EasyLoading.showToast("该锁已被重置".tr, 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) { AppLog.log('连接失败 重连了: $e'); attempt++; // Increase the attempt count if (attempt < maxAttempts) { AppLog.log('重新尝试连接...'); } } } if (attempt >= maxAttempts) { AppLog.log('$maxAttempts次后尝试连接失败'); connectStateCallBack(BluetoothConnectionState.disconnected); } // await bluetoothConnectDevice!.connect(); if (bluetoothConnectionState == BluetoothConnectionState.connected) { try { bluetoothConnectDevice!.discoverServices().then((services) { for (BluetoothService service in services) { // AppLog.log("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) { // Get.log("22222characteristic.remoteId:${characteristic.remoteId}" // " characteristic.uuid:${characteristic.uuid}" // " characteristic.secondaryServiceUuid:${characteristic.secondaryServiceUuid}" // " characteristic.characteristicUuid:${characteristic.characteristicUuid}"); if (characteristic.characteristicUuid == _characteristicIdSubscription) { _subScribeToCharacteristic(characteristic); // AppLog.log('Discovering services finished'); bluetoothConnectionState = BluetoothConnectionState.connected; connectStateCallBack(bluetoothConnectionState!); } } } } }); } on Exception catch (e) { bluetoothConnectionState = BluetoothConnectionState.disconnected; connectStateCallBack(bluetoothConnectionState!); AppLog.log( '发现设备时失败 e:$e bluetoothConnectionState:$bluetoothConnectionState'); rethrow; } } } // 听上报来的数据,参数来自前面扫描到的结果 var allData = []; // 保存上一次的数据,用来判断是否收到重复的数据 var lastTimeData = []; int? dataLen; _subScribeToCharacteristic(BluetoothCharacteristic characteristic) async { final subscription = characteristic.onValueReceived.listen((data) { AppLog.log("订阅获取的数据:$data"); if (data == lastTimeData || data.isEmpty) { return; } else { lastTimeData = data; } // code to handle incoming data // AppLog.log("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位用来指示后面数据块内容的长度 // AppLog.log("dataLen1111:$dataLen getDataLength:${data.length} data:$data"); if (dataLen! + 14 > data.length) { // 当前包的长度小于实际的包时 分包添加 不解析 allData.addAll(data); } else { // 当前包的长度小于实际的包时 不分包 解析 allData.addAll(data); // AppLog.log("dataLen2222:$dataLen getDataLength:${data.length}"); CommandReciverManager.appDataReceive(allData); // 发送完解析初始化数组 allData = []; } } else { // 当包没有头时 是分包的包 直接添加 allData.addAll(data); // var len = allData[8] * 256 + allData[9]; AppLog.log("dataLen3333:$dataLen allData.length:${allData.length} allData:$allData"); if ((dataLen! + 14) <= allData.length) { // 当长度小于等于当前包的数据时 直接解析数据 CommandReciverManager.appDataReceive(allData); // 发送完解析初始化数组 allData = []; } } }); // cleanup: cancel subscription when disconnected bluetoothConnectDevice!.cancelWhenDisconnected(subscription); // enable notifications await characteristic.setNotifyValue(true); // characteristic.setNotifyValue(true).then((_) { // AppLog.log("启动对特性的通知。当特性的值发生变化时,设备会发送一个通知"); // characteristic.lastValueStream.listen((data) { // AppLog.log("订阅获取的数据:$data"); // // do something with new value // if(data == lastTimeData || data.isEmpty){ // return; // }else{ // lastTimeData = data; // } // // code to handle incoming data // // AppLog.log("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位用来指示后面数据块内容的长度 // // AppLog.log("dataLen1111:$dataLen getDataLength:${data.length}"); // if (dataLen! + 12 > data.length) { // // 当前包的长度小于实际的包时 分包添加 不解析 // allData.addAll(data); // } else { // // 当前包的长度小于实际的包时 不分包 解析 // allData.addAll(data); // // AppLog.log("dataLen2222:$dataLen getDataLength:${data.length}"); // CommandReciverManager.appDataReceive(allData); // // 发送完解析初始化数组 // allData = []; // } // } else { // // 当包没有头时 是分包的包 直接添加 // allData.addAll(data); // // var len = allData[8] * 256 + allData[9]; // // AppLog.log("dataLen3333:$dataLen"); // if ((dataLen! + 14) <= allData.length) { // // AppLog.log("44444数据被解析了"); // // 当长度小于等于当前包的数据时 直接解析数据 // CommandReciverManager.appDataReceive(allData); // // 发送完解析初始化数组 // allData = []; // } // } // }); // }); } // 写入 Future writeCharacteristicWithResponse(List value) async { List services = await bluetoothConnectDevice!.discoverServices(); for (BluetoothService service in services) { // AppLog.log("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) { // AppLog.log("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!); // AppLog.log('writeCharacteristicWithResponse _mtuSize:$_mtuSize 得到的分割数据:$subData'); for (int i = 0; i < subData.length; i++) { if (characteristic.properties.writeWithoutResponse) { // 使用WRITE_NO_RESPONSE属性写入值 await characteristic .write(subData[i], withoutResponse: true) .then((value) async { // await Future.delayed(const Duration(milliseconds: 1)).then(( // value) async { // AppLog.log('分包发送成功了'); // }); }); } else if (characteristic.properties.write) { // 使用WRITE属性写入值 await characteristic.write(subData[i]).then((value) async { // await Future.delayed(const Duration(milliseconds: 1)).then(( // value) async { // AppLog.log('分包发送成功了'); // }); }); } else { // 特性不支持写入 throw Exception( 'This characteristic does not support writing.'); } } } on Exception catch (e, s) { AppLog.log('APP写入失败: $e'); 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!); // AppLog.log('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 { // AppLog.log('分包发送成功了'); // }); // }); // } // } on Exception catch (e, s) { // AppLog.log('Error occurred when writing: $e'); // AppLog.log(s); // rethrow; // } } // 读取 // Future> _readCharacteristic(QualifiedCharacteristic characteristic) async { // try { // final result = // await _flutterReactiveBle!.readCharacteristic(characteristic); // AppLog.log("readListresult$result"); // return result; // } on Exception catch (e, s) { // AppLog.log( // '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 // AppLog.log(s); // rethrow; // } // } // 停止扫描蓝牙设备 Future stopScan() async { try { await FlutterBluePlus.stopScan(); } catch (e) { AppLog.log("停止扫描失败"); } } // 断开连接 Future disconnect() async { try { // if(bluetoothConnectDevice != null && bluetoothConnectDevice!.connectionState == BluetoothConnectionState.connected){ connectDeviceMacAddress = ""; if (bluetoothConnectionState == BluetoothConnectionState.connected) { await bluetoothConnectDevice!.disconnect(); AppLog.log("断开连接成功"); } // } } on Exception catch (e, _) { AppLog.log("断开连接失败: $e"); } finally { bluetoothConnectionState = BluetoothConnectionState.disconnected; } } openBlue() async { if (Platform.isAndroid) { await FlutterBluePlus.turnOn(); } if (Platform.isIOS) { EasyLoading.showToast("请开启蓝牙", duration: 2000.milliseconds); } } disposed() { _sendStreamSubscription?.cancel(); _mtuSubscription!.cancel(); // _scanResultsSubscription!.cancel(); _adapterStateStateSubscription!.cancel(); _connectionStateSubscription!.cancel(); } }