import 'dart:convert'; import 'dart:typed_data'; import 'package:app_settings/app_settings.dart'; import '/data/models/appconfig.dart'; import '/data/models/user_Info.dart'; import '/data/services/network/api.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'dart:async'; import 'package:permission_handler/permission_handler.dart'; import '../../../routes/app_routes.dart'; import '../../../core/utils/logger.dart'; import 'dart:io'; import '../../../data/services/bluetooth_manager.dart'; import '../../../data/services/ble_manager.dart'; import '../../../core/utils/permission_util.dart'; /// 配对状态枚举 - 简化版本 enum PairingState { idle, // 空闲/初始状态 checking, // 检查中(蓝牙、权限等) waitingClassic, // 等待经典蓝牙连接 verifying, // 验证设备 binding, //确认绑定设备 manualbinding, //手动绑定设备 associating, // 正在进行BLE设备关联 waitingBle, //等待BLE连接 completed, //配对完成 error, // 错误状态 } /// 错误类型枚举 enum ErrorType { none, bluetoothOff, // 蓝牙关闭 noPermission, // 无权限 noClassicDevice, // 无经典蓝牙设备 deviceNotMatch, // 设备不匹配 deviceBound, // 设备已被绑定 associationFailed, // 关联失败 bleTimeout, // BLE连接超时 authnFailed, // 授权失败 networkError, // 网络错误 } /// 配对控制器 - 基于简化状态机的实现 class PairingController extends GetxController { static const String _tag = 'PairingCtrl'; static PairingController get to => Get.find(); // ========== 状态管理 ========== final _currentState = PairingState.idle.obs; final _errorType = ErrorType.none.obs; final _errorMessage = ''.obs; PairingState get currentState => _currentState.value; ErrorType get errorType => _errorType.value; String get errorMessage => _errorMessage.value; // ========== UI状态 ========== final statusText = ''.obs; final isLoading = false.obs; final showConnectButton = false.obs; final showRetryButton = false.obs; final showBindButton = false.obs; final showRetryChectButton = false.obs; final showAutoCodeInput = false.obs; final showSkipButton = false.obs; // 增加临时跳过绑定按钮状态 final showSkipBindingButton = false.obs; // 新增临时跳过绑定按钮 final connectButtonText = 'connectDevice'.tr.obs; //连接设备 final retryButtonText = 'retry'.tr.obs; final deviceCode = ''.obs; bool isShowSkipButton = false; //是否显示跳过按钮 final availableDevices = [].obs; // 可用设备列表 final selectedDevice = Rx(null); // 用户选中的设备 // ========== 监听器管理 ========== final List _workers = []; Timer? _bleTimeoutTimer; // ========== 依赖服务 ========== late final BluetoothManager _bluetoothManager; late final BleManager _bleManager; // ========== 当前设备信息 ========== BluetoothDevice? _currentClassicDevice; String? _verifiedDeviceAddress; TextEditingController codeInputController = TextEditingController(); // Public getter for view access BluetoothDevice? get currentDevice => _currentClassicDevice; @override void onInit() { super.onInit(); Logger.i(_tag, '配对控制器初始化'); // 确保服务已初始化 _bluetoothManager = Get.find(); _bleManager = Get.find(); // 集中设置所有监听器 _setupAllListeners(); // 开始初始状态检查 // 延迟稍长时间,确保BluetoothManager有足够时间获取已连接设备 Future.delayed(const Duration(milliseconds: 300), () { _startInitialCheck(); }); final app_authcode_jump = AppConfig.env('APP_AUTHCODE_JUMP') ?? ""; //print('app_authcode_jump: $app_authcode_jump'); if (app_authcode_jump == "true") { isShowSkipButton = true; // 启用跳过按钮 } } @override void onClose() { Logger.i(_tag, '配对控制器销毁'); // 清理所有Worker for (var worker in _workers) { worker.dispose(); } _workers.clear(); // 清理定时器 _bleTimeoutTimer?.cancel(); super.onClose(); } // ==================== 监听器设置 ==================== /// 集中设置所有监听器 void _setupAllListeners() { // 1. 监听蓝牙开关状态 _setupBluetoothStateListener(); // 2. 监听经典蓝牙连接状态 _setupClassicConnectionListener(); // 3. 监听BLE连接状态 _setupBleConnectionListener(); } /// 监听蓝牙开关状态 void _setupBluetoothStateListener() { _workers.add(ever(_bluetoothManager.bluetoothStateRx, (String state) { Logger.d(_tag, '蓝牙状态变化: $state'); _handleBluetoothStateChange(state); })); } /// 监听经典蓝牙连接状态 void _setupClassicConnectionListener() { _workers .add(ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) { Logger.d(_tag, '经典蓝牙设备变化: ${device?.name}'); _handleClassicDeviceChange(device); })); } /// 监听BLE连接状态 void _setupBleConnectionListener() { _workers.add(ever(_bleManager.connectionStateRx, (int state) { Logger.d(_tag, 'BLE连接状态变化: $state'); _handleBleStateChange(state); })); } // ==================== 状态处理 ==================== /// 处理蓝牙开关状态变化 void _handleBluetoothStateChange(String state) { if (state == 'off') { _setError(ErrorType.bluetoothOff, 'pleaseEnableBluetooth'.tr); } else if (state == 'on' && _errorType.value == ErrorType.bluetoothOff) { // 蓝牙重新开启,恢复流程 Logger.i(_tag, '检测到蓝牙已开启,自动恢复配对流程'); _clearError(); // 延迟一下确保蓝牙服务完全就绪 Future.delayed(const Duration(milliseconds: 500), () { _checkCurrentStatus(); }); } } /// 处理经典蓝牙设备变化 void _handleClassicDeviceChange(BluetoothDevice? device) { _currentClassicDevice = device; switch (_currentState.value) { case PairingState.waitingClassic: if (device != null) { // 有设备连接,进入验证阶段 Logger.i(_tag, '检测到经典蓝牙设备连接,开始验证'); _transition(PairingState.verifying); _verifyDevice(device); } break; case PairingState.error: // 如果在错误状态下检测到设备连接,且错误是无设备连接,则自动恢复 if (device != null && _errorType.value == ErrorType.noClassicDevice) { Logger.i(_tag, '检测到设备重新连接,自动恢复配对流程'); _clearError(); _transition(PairingState.verifying); _verifyDevice(device); } break; case PairingState.verifying: case PairingState.waitingBle: case PairingState.completed: if (device == null) { // 设备断开,返回等待连接状态 _setError(ErrorType.noClassicDevice, 'deviceDisconnected'.tr); //设备已断开 } break; default: break; } } /// 处理BLE状态变化 void _handleBleStateChange(int state) { if (_currentState.value == PairingState.waitingBle) { if (state == 2) { // BLE已连接 _bleTimeoutTimer?.cancel(); _transition(PairingState.completed); } } // 如果在完成状态下BLE断开,显示警告但不改变状态 if (_currentState.value == PairingState.completed && state != 2) { Logger.w(_tag, 'BLE连接已断开,但配对流程已完成'); } } // ==================== 状态转换 ==================== /// 状态转换 void _transition(PairingState newState) { final oldState = _currentState.value; _currentState.value = newState; Logger.i(_tag, '状态转换: $oldState -> $newState'); // 根据新状态执行相应操作 _onStateChanged(newState); } /// 状态变化处理 void _onStateChanged(PairingState state) { // 重置UI状态 isLoading.value = false; showConnectButton.value = false; showRetryButton.value = false; showSkipBindingButton.value = false; // 重置临时跳过绑定按钮 showSkipButton.value = false; showAutoCodeInput.value = false; showBindButton.value = false; showRetryChectButton.value = false; switch (state) { case PairingState.idle: statusText.value = 'readyToStartPairing'.tr; break; case PairingState.checking: statusText.value = 'checkingEnvironment'.tr; isLoading.value = true; break; case PairingState.waitingClassic: statusText.value = 'ensureHeadsetOnAndPairingMode'.tr; showConnectButton.value = true; showSkipButton.value = isShowSkipButton; connectButtonText.value = 'goToBluetoothSettings'.tr; break; case PairingState.verifying: statusText.value = 'verifyingDevice'.tr; isLoading.value = true; break; case PairingState.binding: statusText.value = 'confirmBinding'.tr; isLoading.value = true; showBindButton.value = true; showRetryChectButton.value = true; break; case PairingState.associating: statusText.value = 'associatingDevice'.tr; isLoading.value = true; // 延迟执行关联,确保状态已更新 Future.delayed(const Duration(milliseconds: 200), () { _startDeviceAssociation(); }); break; case PairingState.waitingBle: statusText.value = 'establishingSecureConnection'.tr; isLoading.value = true; // 延迟一下再调用,给BLE管理器时间更新状态 Future.delayed(const Duration(milliseconds: 200), () { _startBleConnection(); }); break; case PairingState.manualbinding: statusText.value = 'needManualBindingAuthCode'.tr; isLoading.value = false; showAutoCodeInput.value = true; // showSkipButton.value = isShowSkipButton; showSkipBindingButton.value = true; // 显示临时跳过绑定按钮 break; case PairingState.completed: statusText.value = 'pairingSuccessful'.tr; isLoading.value = false; _navigateToHome(); break; case PairingState.error: statusText.value = _errorMessage.value; isLoading.value = false; showSkipButton.value = isShowSkipButton; // 根据错误类型决定显示哪个按钮和按钮文本 switch (_errorType.value) { case ErrorType.bluetoothOff: showConnectButton.value = true; connectButtonText.value = 'enableBluetooth'.tr; //开启蓝牙 break; case ErrorType.noClassicDevice: showConnectButton.value = true; connectButtonText.value = 'goToBluetoothSettings'.tr; //前往蓝牙设备 break; case ErrorType.noPermission: showRetryButton.value = true; retryButtonText.value = 'grantPermissions'.tr; //授予权限 break; case ErrorType.associationFailed: showRetryButton.value = true; retryButtonText.value = 'retryAssociation'.tr; //重新关联 break; case ErrorType.authnFailed: showRetryButton.value = true; retryButtonText.value = 'retryAuthorization'.tr; //重新授权 break; default: showRetryButton.value = true; retryButtonText.value = 'retry'.tr; //重试 break; } break; } } // ==================== 错误处理 ==================== /// 设置错误状态 void _setError(ErrorType type, String message) { _errorType.value = type; _errorMessage.value = message; _transition(PairingState.error); } /// 清除错误状态 void _clearError() { _errorType.value = ErrorType.none; _errorMessage.value = ''; } // ==================== 核心流程 ==================== /// 开始初始检查 void _startInitialCheck() { _transition(PairingState.checking); _checkCurrentStatus(); } /// 检查当前状态并决定下一步 void _checkCurrentStatus() async { try { // 1. 检查蓝牙状态 final results = await Future.wait([ _checkBluetoothState(), // 检查蓝牙状态 _checkPermissions(), // 检查权限 _bluetoothManager.refreshDeviceConnection(), // 刷新设备连接 ]); final isBluetoothOk = results[0] as bool; final arePermissionsOk = results[1] as bool; if (!isBluetoothOk) { _setError(ErrorType.bluetoothOff, 'pleaseEnableBluetooth'.tr); return; } // 2. 检查权限 if (!arePermissionsOk) { _setError(ErrorType.noPermission, 'pleaseGrantNecessaryPermissions'.tr); return; } // 3. 先刷新设备连接状态,确保获取最新的连接信息 await _bluetoothManager.refreshDeviceConnection(); // 4. 检查经典蓝牙连接 final classicDevice = _bluetoothManager.currentDevice; if (classicDevice == null) { _transition(PairingState.waitingClassic); return; } // 5. 如果有设备,进行验证 _currentClassicDevice = classicDevice; _transition(PairingState.verifying); await _verifyDevice(classicDevice); } catch (e) { Logger.e(_tag, '状态检查失败: $e'); _setError(ErrorType.networkError, 'checkFailedRetry'.tr); } } /// 新增一个辅助方法来检查蓝牙状态 Future _checkBluetoothState() async { return _bluetoothManager.bluetoothState != 'off'; } /// 检查权限 Future _checkPermissions() async { // Android权限检查 if (Platform.isAndroid) { Logger.i(_tag, '开始检查Android权限'); // 检查蓝牙相关权限 final bluetoothScanGranted = await PermissionUtil.instance.requestPermission( permissionType: Permission.bluetoothScan, permissionName: 'bluetoothScan'.tr, explanationText: 'bluetoothScanExplanation'.tr, permanentDenialText: 'bluetoothScanPermanentDenial'.tr, ); final bluetoothConnectGranted = await PermissionUtil.instance.requestPermission( permissionType: Permission.bluetoothConnect, permissionName: 'bluetoothConnect'.tr, explanationText: 'bluetoothConnectExplanation'.tr, permanentDenialText: 'bluetoothConnectPermanentDenial'.tr, ); final locationGranted = await PermissionUtil.instance.requestPermission( permissionType: Permission.locationWhenInUse, permissionName: 'locationInfo'.tr, explanationText: 'locationForBluetoothExplanation'.tr, permanentDenialText: 'locationPermanentDenial'.tr, ); return bluetoothScanGranted && bluetoothConnectGranted && locationGranted; } return true; } /// 验证设备 Future _verifyDevice(BluetoothDevice device) async { try { Logger.i(_tag, '开始验证设备: ${device.name} (${device.address})'); final result = await authbindingDevice(device); if (result == 10) { //验证失败 进入手动授权 await connectble(device); } else if (result == 9) { Logger.i(_tag, 'BLE已连接,直接完成配对'); _transition(PairingState.completed); } else if (result == 1) { //跳转绑定界面 //验证失败 进入手动授权 if (currentDevice != null) { _transition(PairingState.binding); } else { _transition(PairingState.checking); _checkCurrentStatus(); } } else { final authcode_open = AppConfig.env("APP_AUTHCODE_OPEN") ?? ""; if (authcode_open == "true") { //验证失败 进入手动授权 _transition(PairingState.manualbinding); } else { _setError(ErrorType.deviceNotMatch, 'pleaseConnectDeepSoundDevice'.tr); //请连接DeepSound设备 } } } catch (e) { Logger.e(_tag, '设备验证异常: $e'); _setError(ErrorType.networkError, 'verificationFailedRetry'.tr); //验证失败请重试 } } //连接ble Future connectble(BluetoothDevice device) async { Logger.i(_tag, '设备验证通过'); // _verifiedDeviceAddress = device.address; // 检查是否已有BLE关联 final pairedMacAddress = await _bleManager.getPairedMacAddress(); Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress'); if (pairedMacAddress != null && pairedMacAddress.toUpperCase() == _verifiedDeviceAddress?.toUpperCase()) { // 已有关联,检查BLE连接状态 Logger.i(_tag, '设备已关联,检查BLE连接状态'); final currentBleState = await _bleManager.getConnectionState(); Logger.i(_tag, '验证时BLE状态: $currentBleState'); if (currentBleState == 2) { // BleConnectionState.connected Logger.i(_tag, 'BLE已连接,直接完成配对'); _transition(PairingState.completed); } else { Logger.i(_tag, 'BLE未连接,等待BLE连接'); _transition(PairingState.waitingBle); } } else { // 没有关联或关联的是其他设备,需要进行关联 Logger.i(_tag, '需要进行BLE设备关联'); _transition(PairingState.associating); } return; } /// 开始设备关联 void _startDeviceAssociation() async { try { if (_verifiedDeviceAddress == null) { _setError( ErrorType.associationFailed, 'invalidDeviceAddress'.tr); //无效的设备地址 return; } Logger.i(_tag, '开始BLE设备关联: $_verifiedDeviceAddress'); // 调用BLE管理器的关联方法 final success = await _bleManager.startDeviceAssociation( deviceNamePattern: 'Voitrans', // 或者使用 _currentClassicDevice?.name macAddress: _verifiedDeviceAddress!, ); if (success) { Logger.i(_tag, 'BLE设备关联成功'); // 关联成功后,转到等待BLE连接状态 _transition(PairingState.waitingBle); } else { _setError(ErrorType.associationFailed, 'bleDeviceAssociationFailed'.tr); //BLE设备关联失败 } } catch (e) { Logger.e(_tag, 'BLE设备关联异常: $e'); _setError(ErrorType.associationFailed, 'deviceAssociationFailedRetry'.tr); //设备关联失败,请重试 } } /// 开始BLE连接 void _startBleConnection() async { try { // 设置超时定时器 _bleTimeoutTimer?.cancel(); _bleTimeoutTimer = Timer(const Duration(seconds: 20), () { if (_currentState.value == PairingState.waitingBle) { _setError(ErrorType.bleTimeout, 'bleConnectionTimeoutRetry'.tr); //BLE连接超时,请重启耳机后再试 } }); // 检查是否已连接 - 直接从原生层获取最新状态 final currentBleState = await _bleManager.getConnectionState(); Logger.i(_tag, 'BLE当前连接状态: $currentBleState'); if (currentBleState == 2) { // BleConnectionState.connected Logger.i(_tag, 'BLE已经连接,直接完成配对'); _bleTimeoutTimer?.cancel(); _transition(PairingState.completed); return; } // 注册后台扫描以开始BLE配对 if (_verifiedDeviceAddress != null) { final success = await _bleManager.registerBackgroundScan( macAddress: _verifiedDeviceAddress); if (!success && _currentState.value == PairingState.waitingBle) { _setError( ErrorType.bleTimeout, 'blePairingStartupFailed'.tr); //BLE配对启动失败 } } } catch (e) { Logger.e(_tag, 'BLE连接失败: $e'); _setError(ErrorType.bleTimeout, 'bleConnectionFailed'.tr); //BLE连接失败 } } //自动绑定设备 0 未合作商 1 合作商 9经典蓝牙已绑定 10,ble蓝牙已绑定 Future authbindingDevice(BluetoothDevice device) async { // 检查设备名称是否包含 DeepSound 或 DeapSound final deviceName = device.name; final names = AppConfig.allproductNames(); // 检查是否已有绑定的设备 print("device.address${device.address}"); final existingDevice = User.instance.devices.firstWhere( (d) => d.devicetype == 1 && d.devicemac == device.address, orElse: () => UserDevice( id: -1, uid: '', devicetype: -1, devicename: '', devicemac: '', license: ''), ); if (existingDevice.id != -1) { // 已经绑定 return 9; } print( '获取到 deviceName: $deviceName address: ${device.address} names:$names'); if (names.contains(deviceName)) { await _bleManager.startScan(deviceName); await Future.delayed(const Duration(seconds: 1)); // 尝试最多读取 3 次设备信息,每次间隔 1 秒 List>? deviceinfos; for (int i = 0; i < 3; i++) { // 使用设备名称获取设备列表 deviceinfos = await _bleManager.getDeviceList(deviceName); print('获取到 deviceinfos: $deviceinfos'); if (deviceinfos != null && deviceinfos.isNotEmpty) { // 循环读取每个设备的hex数据 for (var deviceInfo in deviceinfos) { String? hexData = deviceInfo["hex"]; if (hexData != null && hexData.length >= 28) { // 确保hex数据长度足够(14字节 = 28个字符) // 读取9-14字节的MAC地址 String macFromHex = extractMacFromHex(hexData, device.address); if (macFromHex.isNotEmpty) { String code = ""; // 找到匹配的设备,提取授权码 if (Platform.isIOS) { // iOS设备,提取13-22字节的授权码 code = extractAndReverseBytes(hexData, 13, 22); print('找到匹配设备,获取到 code: $code'); if (code != "") { _bleManager.stopScan(); deviceCode.value = code; String? uuids = deviceInfo["id"]; _verifiedDeviceAddress = uuids; print('找到匹配设备,获取到 uuids: $uuids'); //检查是否已经绑定 final existingDevice = User.instance.devices.firstWhere( (d) => d.devicetype == 2 && d.license != "" && d.devicemac == device.address, orElse: () => UserDevice( id: -1, uid: '', devicetype: -1, devicename: '', devicemac: '', license: ''), ); if (existingDevice.id != -1) { // 已经绑定 return 10; } else { return 1; } } } else if (Platform.isAndroid) { // Android设备,提取15-24字节的授权码 code = extractAndReverseBytes(hexData, 15, 24); print('找到匹配设备,获取到 code: $code'); if (code != "") { _bleManager.stopScan(); deviceCode.value = code; _verifiedDeviceAddress = device.address; //检查是否已经绑定 final existingDevice = User.instance.devices.firstWhere( (d) => d.devicetype == 2 && d.license != "" && d.devicemac == device.address, orElse: () => UserDevice( id: -1, uid: '', devicetype: -1, devicename: '', devicemac: '', license: ''), ); if (existingDevice.id != -1) { // 已经绑定 return 10; } else { return 1; } } } else { break; } } } } } await Future.delayed(Duration(seconds: 1)); } return 1; } return 0; //可以跳转1 } // 新增方法:从hex数据中提取MAC地址并与当前设备MAC对比 String extractMacFromHex(String hexData, String deviceMac) { try { // 将hex字符串转换为字节数组 List bytes = []; for (int i = 0; i < hexData.length; i += 2) { bytes.add(int.parse(hexData.substring(i, i + 2), radix: 16)); } // 读取9-14字节(索引8-13)的MAC地址 if (bytes.length < 14) { return ""; } List macBytes = []; if (Platform.isIOS) { for (int i = 7; i <= 12; i++) { // 每个字节异或0x5A int decodedByte = bytes[i] ^ 0x5A; macBytes.add(decodedByte); } } else if (Platform.isAndroid) { for (int i = 9; i <= 14; i++) { // 每个字节异或0x5A int decodedByte = bytes[i] ^ 0x5A; macBytes.add(decodedByte); } } // 将MAC字节转换为MAC地址字符串格式 String extractedMac = macBytes .map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()) .join(':'); // 格式化当前设备MAC地址(确保格式一致) String formattedDeviceMac = deviceMac.replaceAll(':', '').toUpperCase(); String formattedExtractedMac = extractedMac.replaceAll(':', '').toUpperCase(); print('设备MAC: $deviceMac, 提取的MAC: $extractedMac'); // 对比MAC地址 if (formattedDeviceMac == formattedExtractedMac) { print('MAC地址匹配成功!'); return extractedMac; } else { print('MAC地址不匹配'); return ""; } } catch (e) { print('提取MAC地址时出错: $e'); return ""; } } //确认绑定设备 void confirmBindDevice() async { final response = await Api.binddevice({ "code": deviceCode.value, "devicename": currentDevice?.name, "devicemac": currentDevice?.address, // 使用 address 替代 deviceId }); Logger.i(_tag, '手动授权结果 ${response}'); if (response != null) { Logger.i(_tag, '绑定设备成功 $response'); if (response['device'] != '') { // 根据API设计调整 final device = UserDevice.fromJson(response['device']); User.instance.addUserDevice(device); _transition(PairingState.verifying); _verifyDevice(_currentClassicDevice!); } return; } else { Logger.e(_tag, '绑定设备失败!'); return; } } int reverseBits(int byte) { // 这里是 nibble swap 还是 bit 反转?看你需求,先保持 nibble swap return ((byte & 0x0F) << 4) | ((byte & 0xF0) >> 4); } String extractAndReverseBytes(String hex, int start, int end) { List bytes = []; for (int i = 0; i < hex.length; i += 2) { bytes.add(int.parse(hex.substring(i, i + 2), radix: 16)); } List slice = bytes.sublist(start, end + 1); List reversed = slice.reversed.toList(); return reversed .map((b) => b.toRadixString(16).padLeft(2, '0')) .join() .toUpperCase(); } /// 用户点击授权码输入框 void onAutoCodeInputTap() async { // 调用BLE管理器的自动绑定方法 final response = await Api.bindauthcode({ "code": codeInputController.text.trim(), "earphonname": currentDevice?.name, "earphonemac": currentDevice?.address, // 使用 address 替代 deviceId }); Logger.i(_tag, '手动授权结果 ${response}'); if (response != null) { // User.instance.earphonemac = currentDevice?.address ?? ''; // 使用 address // User.instance.earphonename = currentDevice?.name ?? ''; // User.instance.earphoneauthcode = codeInputController.text.trim(); _transition(PairingState.verifying); _verifyDevice(_currentClassicDevice!); } else { Logger.e(_tag, '手动绑定失败!'); _setError(ErrorType.authnFailed, 'deviceAuthorizationFailedCheckCode'.tr); //设备授权失败,请检查授权码 } } /// 导航到主页 void _navigateToHome() { Future.delayed(const Duration(milliseconds: 500), () async { // 启动AgentService服务 try { Logger.i(_tag, '启动AgentService服务'); await _bleManager.startAgentService(); } catch (e) { Logger.e(_tag, '启动AgentService失败: $e'); } Get.offAllNamed(Routes.home); }); } // ==================== 用户操作 ==================== /// 用户点击连接按钮 void onConnectTap() { Logger.i(_tag, '用户点击连接按钮'); // 根据当前状态或错误类型决定行为 if (_currentState.value == PairingState.error) { switch (_errorType.value) { case ErrorType.bluetoothOff: // 引导用户去开启蓝牙 Logger.i(_tag, '引导用户开启蓝牙'); AppSettings.openAppSettings(type: AppSettingsType.bluetooth); break; case ErrorType.noClassicDevice: // 引导用户去蓝牙设置连接设备 Logger.i(_tag, '引导用户去蓝牙设置'); AppSettings.openAppSettings(type: AppSettingsType.bluetooth); break; default: // 其他错误情况,刷新并重试 _bluetoothManager.refreshDeviceConnection(); _checkCurrentStatus(); break; } } else if (_currentState.value == PairingState.waitingClassic) { // 等待经典蓝牙连接状态,引导去设置 Logger.i(_tag, '等待经典蓝牙连接,引导用户去蓝牙设置'); AppSettings.openAppSettings(type: AppSettingsType.bluetooth); } else { // 其他情况,刷新设备连接 _bluetoothManager.refreshDeviceConnection(); _checkCurrentStatus(); } } /// 用户点击重试按钮 void onRetryTap() { Logger.i(_tag, '用户点击重试按钮'); // 如果是权限问题,引导去设置 if (_errorType.value == ErrorType.noPermission) { Logger.i(_tag, '引导用户去应用设置授予权限'); AppSettings.openAppSettings(); } else { // 其他情况,清除错误并重试 _clearError(); _startInitialCheck(); } } /// 用户点击跳过绑定按钮 void onSkipBindingTap() { Logger.i(_tag, '用户选择临时跳过手动绑定'); User.instance.addUserDevice( UserDevice( id: 0, // 临时设备ID uid: User.instance.uid, devicetype: 1, devicemac: _currentClassicDevice?.address ?? '', devicename: _currentClassicDevice?.name ?? 'Unknown Device', license: "", // 临时授权码 ), ); _transition(PairingState.verifying); _verifyDevice(_currentClassicDevice!); } /// 用户点击跳过按钮 void onSkipTap() async { Logger.i(_tag, '用户选择跳过配对'); // 启动AgentService服务 try { Logger.i(_tag, '启动AgentService服务'); await _bleManager.startAgentService(); } catch (e) { Logger.e(_tag, '启动AgentService失败: $e'); } Get.offAllNamed(Routes.home); } /// 打开蓝牙设置 void openBluetoothSettings() { AppSettings.openAppSettings(type: AppSettingsType.bluetooth); } /// 清除设备关联(在需要重新配对时调用) Future clearDeviceAssociation() async { try { Logger.i(_tag, '清除设备关联'); await _bleManager.clearPairedDevices(); } catch (e) { Logger.e(_tag, '清除设备关联失败: $e'); } } // 用户选择设备后调用 void onDeviceSelected(BluetoothDevice device) { Logger.i(_tag, '用户选择了设备: ${device.name} (${device.address})'); selectedDevice.value = device; _currentClassicDevice = device; _transition(PairingState.verifying); _verifyDevice(device); } }