From dc37b42977fbb4daf32205c94a25a60fe99eb3fe Mon Sep 17 00:00:00 2001 From: liyi Date: Mon, 3 Mar 2025 18:29:37 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=A2=9E=E5=8A=A0=E5=85=BC?= =?UTF-8?q?=E5=AE=B932bit=E5=B9=BF=E6=92=AD=E4=BF=A1=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/blue/blue_manage.dart | 70 ++++++++++-- lib/blue/io_type.dart | 8 +- .../addLock/nearbyLock/nearbyLock_logic.dart | 105 ++++++++++++++++-- .../addLock/nearbyLock/nearbyLock_page.dart | 34 +++--- 4 files changed, 179 insertions(+), 38 deletions(-) diff --git a/lib/blue/blue_manage.dart b/lib/blue/blue_manage.dart index 97873775..9aa7e77d 100755 --- a/lib/blue/blue_manage.dart +++ b/lib/blue/blue_manage.dart @@ -253,14 +253,20 @@ class BlueManage { FlutterBluePlus.scanResults.listen((List results) { scanDevices.clear(); for (final ScanResult scanResult in results) { - // AppLog.log('扫描到的设备:${scanResult.device.platformName} ${scanResult.advertisementData.advName} ${scanResult.rssi}'); + if (scanResult.advertisementData.serviceUuids.isNotEmpty) { + // AppLog.log( + // '扫描到的设备:${scanResult.advertisementData.serviceUuids[0].toString()}'); + } else { + continue; + } + + final isMatch = _isMatch( + scanResult.advertisementData.serviceUuids + .map((e) => e.uuid) + .toList(), + deviceType); // 判断名字为空的直接剔除 - if (((scanResult.advertisementData.serviceUuids.isNotEmpty - ? scanResult.advertisementData.serviceUuids[0] - : '') - .toString() - .contains(getDeviceType(deviceType))) && - (scanResult.rssi >= -100)) { + if (isMatch && (scanResult.rssi >= -100)) { // 查询id相同的元素 final int knownDeviceIndex = scanDevices.indexWhere( (ScanResult d) => @@ -300,6 +306,23 @@ class BlueManage { }); } + /// 判断是否包含指定的uuid + bool _isMatch(List serviceUuids, DeviceType deviceType) { + // 获取设备类型数组 + List deviceTypeList = getDeviceType(deviceType); + + // 检查 serviceUuids 是否包含 deviceTypeList 中的任意一个值 + if (serviceUuids != null && serviceUuids.isNotEmpty) { + return serviceUuids.any((uuid) { + return deviceTypeList + .any((type) => uuid.toLowerCase().contains(type.toLowerCase())); + }); + } + + // 如果 serviceUuids 为空,则返回 false + return false; + } + /// 调用发送数据 List senderData, Future blueSendData( String deviceName, ConnectStateCallBack stateCallBack, @@ -499,8 +522,39 @@ class BlueManage { } AppLog.log('调用了停止扫描的方法'); await stopScan(); + if (scanResult.advertisementData.serviceUuids[0].toString().length >= 5 && + (scanResult.advertisementData.serviceUuids[0].toString()[5] == '0') && + isAddEquipment == false) { + // 添加这个判断是因为有些苹果设备或者安卓等性能比较好的设备时,添加完锁之后,锁板未改变为已添加状态之前,就进行了蓝牙连接,导致添加完锁就失败,这里进行了判断,如果第一次连接失败,就清除缓存重新扫描连接 + if (isReconnect == true) { + AppLog.log('该锁已被重置, 重新发送扫描命令'); - if ((scanResult.advertisementData.serviceUuids[0].toString()[31] == '0') && + BuglyTool.uploadException( + message: '该锁已被重置, 重新发送扫描命令startScanSingle 上传记录当前方法是:_connectDevice', + detail: + '添加这个判断是因为有些苹果设备或者安卓等性能比较好的设备时,添加完锁之后,锁板未改变为已添加状态之前,就进行了蓝牙连接,导致添加完锁就失败,这里进行了判断,如果第一次连接失败,就清除缓存重新扫描连接 该锁已被重置, 重新发送扫描命令 serviceUuids:${scanResult.advertisementData.serviceUuids[0].toString()}', + upload: false); + + scanDevices.clear(); + startScanSingle(deviceName, 15, (List scanDevices) { + _connectDevice(scanDevices, deviceName, connectStateCallBack, + isAddEquipment: isAddEquipment, isReconnect: false); + }); + } else { + connectStateCallBack(BluetoothConnectionState.disconnected); + EasyLoading.showToast('该锁已被重置'.tr, duration: 2000.milliseconds); + scanDevices.clear(); + + BuglyTool.uploadException( + message: '提示该锁已被重置, 回调断开连接, 清除缓存,上传记录当前方法是:_connectDevice', + detail: + 'isReconnect:$isReconnect serviceUuids:${scanResult.advertisementData.serviceUuids[0].toString()}', + upload: false); + } + return; + } + if (scanResult.advertisementData.serviceUuids[0].toString().length >= 30 && + (scanResult.advertisementData.serviceUuids[0].toString()[31] == '0') && isAddEquipment == false) { // 添加这个判断是因为有些苹果设备或者安卓等性能比较好的设备时,添加完锁之后,锁板未改变为已添加状态之前,就进行了蓝牙连接,导致添加完锁就失败,这里进行了判断,如果第一次连接失败,就清除缓存重新扫描连接 if (isReconnect == true) { diff --git a/lib/blue/io_type.dart b/lib/blue/io_type.dart index 828176c6..ee785811 100755 --- a/lib/blue/io_type.dart +++ b/lib/blue/io_type.dart @@ -5,14 +5,14 @@ enum DeviceType { gateway // 758825 } -String getDeviceType(DeviceType deviceType) { - String t = '758824'; +List getDeviceType(DeviceType deviceType) { + List t = ['758824']; switch (deviceType) { case DeviceType.blue: - t = '758824'; + t = ['758824', '75']; break; case DeviceType.gateway: - t = '758825'; + t = ['758825']; break; } return t; diff --git a/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart b/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart index 808ed7de..b607e6d1 100755 --- a/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart +++ b/lib/mine/addLock/nearbyLock/nearbyLock_logic.dart @@ -51,9 +51,9 @@ class NearbyLockLogic extends BaseGetXController { }); BlueManage().blueSendData(deviceName, (BluetoothConnectionState state) async { - // AppLog.log('点击要添加的设备了'); + AppLog.log('点击要添加的设备了'); if (state == BluetoothConnectionState.connected) { - // AppLog.log('开始获取公钥'); + AppLog.log('开始获取公钥'); IoSenderManage.getPublicKey(lockId: deviceName); } else if (state == BluetoothConnectionState.disconnected) { dismissEasyLoading(); @@ -395,19 +395,104 @@ class NearbyLockLogic extends BaseGetXController { void startScanBlueList() { BlueManage().startScan(2000, DeviceType.blue, (List list) { state.devices.clear(); - for (int i = 0; i < list.length; i++) { - final ScanResult device = list[i]; - if ((device.advertisementData.serviceUuids.isNotEmpty - ? device.advertisementData.serviceUuids[0] - : '') - .toString()[31] != - '1') { - state.devices.add(list[i]); + + for (final device in list) { + final String? serviceUuid = + device.advertisementData.serviceUuids.isNotEmpty + ? device.advertisementData.serviceUuids[0].toString() + : null; + + if (serviceUuid != null && !isPaired(serviceUuid)) { + state.devices.add(device); } } }); } + /// 判断是否已配对(支持 128-bit 和 32-bit) + bool isPaired(String serviceUuid) { + if (serviceUuid.length < 6) return false; // 最短需要 6 个字符才能判断 + + try { + if (serviceUuid.length >= 32) { + // 128-bit UUID:检查第 31 和 32 位 + String status = serviceUuid.substring(30, 32); + return status == '01'; // '01' 表示已配对 + } else if (serviceUuid.length >= 5) { + // 32-bit UUID:检查第 4 和 5 位 + String status = serviceUuid.substring(4, 6); + return status == '01'; // '01' 表示已配对 + } + return false; // 如果长度不足,则返回 false + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + + /// 判断是否休眠(支持 128-bit 和 32-bit) + bool isSleeping(String serviceUuid) { + if (serviceUuid.length < 8) return false; // 最短需要 8 个字符才能判断 + + try { + if (serviceUuid.length >= 34) { + // 128-bit UUID:检查第 33 和 34 位 + String status = serviceUuid.substring(32, 34); + return status == '00'; // '00' 表示休眠 + } else if (serviceUuid.length >= 7) { + // 32-bit UUID:检查第 6 和 7 位 + String status = serviceUuid.substring(6, 8); + return status == '00'; // '00' 表示休眠 + } + return false; // 如果长度不足,则返回 false + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + + /// 判断 128-bit UUID 是否已配对 + bool isPaired128Bit(String serviceUuid) { + if (serviceUuid.length != 36) return false; // 确保是 128-bit UUID + try { + String status = serviceUuid.substring(30, 32); // 获取第 31 和 32 位 + return status == '01'; // '01' 表示已配对 + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + + /// 判断 128-bit UUID 是否休眠 + bool isSleeping128Bit(String serviceUuid) { + if (serviceUuid.length != 36) return false; // 确保是 128-bit UUID + try { + String status = serviceUuid.substring(32, 34); // 获取第 33 和 34 位 + return status == '00'; // '00' 表示休眠 + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + + /// 判断 32-bit UUID 是否已配对 + bool isPaired32Bit(String serviceUuid) { + if (serviceUuid.length != 8) return false; // 确保是 32-bit UUID + try { + String status = serviceUuid.substring(3, 5); // 获取第 4 和 5 位 + return status == '01'; // '01' 表示已配对 + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + + /// 判断 32-bit UUID 是否休眠 + bool isSleeping32Bit(String serviceUuid) { + if (serviceUuid.length != 8) return false; // 确保是 32-bit UUID + try { + String status = serviceUuid.substring(5, 7); // 获取第 6 和 7 位 + return status == '00'; // '00' 表示休眠 + } catch (e) { + return false; // 如果索引越界或其他错误,返回 false + } + } + void stopScanBlueList() { BlueManage().disconnect(); BlueManage().stopScan(); diff --git a/lib/mine/addLock/nearbyLock/nearbyLock_page.dart b/lib/mine/addLock/nearbyLock/nearbyLock_page.dart index 97275540..25413554 100755 --- a/lib/mine/addLock/nearbyLock/nearbyLock_page.dart +++ b/lib/mine/addLock/nearbyLock/nearbyLock_page.dart @@ -106,13 +106,18 @@ class _NearbyLockPageState extends State with RouteAware { Widget nearbyLockItem( String lockTypeIcon, ScanResult scanResult, Function() action) { return GestureDetector( - onTap: ((scanResult.advertisementData.serviceUuids.isNotEmpty - ? scanResult.advertisementData.serviceUuids[0] - : '') - .toString()[33] == - '1') - ? action - : null, + onTap: () { + final String? serviceUuid = + scanResult.advertisementData.serviceUuids.isNotEmpty + ? scanResult.advertisementData.serviceUuids[0].toString() + : null; + + // 检查 serviceUuid 是否存在且长度足够,并判断第 34 个字符是否为 '1' + final isPaired = !logic.isPaired(serviceUuid!); + if (serviceUuid != null && isPaired) { + action(); + } + }, child: Column( children: [ Container( @@ -136,15 +141,12 @@ class _NearbyLockPageState extends State with RouteAware { Text(scanResult.advertisementData.advName, style: TextStyle( fontSize: 20.sp, - color: ((scanResult.advertisementData.serviceUuids - .isNotEmpty - ? scanResult.advertisementData - .serviceUuids[0] - : '') - .toString()[33] == - '1') - ? AppColors.blackColor - : Colors.grey)), + color: logic.isSleeping( + scanResult.advertisementData.serviceUuids[0] + .toString(), + ) + ? Colors.grey + : AppColors.blackColor)), ], ), SizedBox(