import 'package:app_settings/app_settings.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, // 验证设备 associating, // 正在进行BLE设备关联 waitingBle, // 等待BLE连接 completed, // 配对完成 error, // 错误状态 } /// 错误类型枚举 enum ErrorType { none, bluetoothOff, // 蓝牙关闭 noPermission, // 无权限 noClassicDevice, // 无经典蓝牙设备 deviceNotMatch, // 设备不匹配 deviceBound, // 设备已被绑定 associationFailed, // 关联失败 bleTimeout, // BLE连接超时 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 showSkipButton = false.obs; final connectButtonText = '连接设备'.obs; final retryButtonText = '重试'.obs; // ========== 监听器管理 ========== final List _workers = []; Timer? _bleTimeoutTimer; // ========== 依赖服务 ========== late final BluetoothManager _bluetoothManager; late final BleManager _bleManager; // ========== 当前设备信息 ========== BluetoothDevice? _currentClassicDevice; String? _verifiedDeviceAddress; // 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(); }); } @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, '请开启蓝牙'); } 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, '设备已断开'); } 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; showSkipButton.value = false; switch (state) { case PairingState.idle: statusText.value = '准备开始配对'; break; case PairingState.checking: statusText.value = '正在检查环境...'; isLoading.value = true; break; case PairingState.waitingClassic: statusText.value = '请确保耳机已开启并进入配对模式'; showConnectButton.value = true; showSkipButton.value = true; connectButtonText.value = '前往蓝牙设置'; break; case PairingState.verifying: statusText.value = '正在验证设备...'; isLoading.value = true; break; case PairingState.associating: statusText.value = '正在关联设备...'; isLoading.value = true; // 延迟执行关联,确保状态已更新 Future.delayed(const Duration(milliseconds: 200), () { _startDeviceAssociation(); }); break; case PairingState.waitingBle: statusText.value = '正在建立安全连接...'; isLoading.value = true; // 延迟一下再调用,给BLE管理器时间更新状态 Future.delayed(const Duration(milliseconds: 200), () { _startBleConnection(); }); break; case PairingState.completed: statusText.value = '配对成功!'; isLoading.value = false; _navigateToHome(); break; case PairingState.error: statusText.value = _errorMessage.value; isLoading.value = false; showSkipButton.value = true; // 根据错误类型决定显示哪个按钮和按钮文本 switch (_errorType.value) { case ErrorType.bluetoothOff: showConnectButton.value = true; connectButtonText.value = '开启蓝牙'; break; case ErrorType.noClassicDevice: showConnectButton.value = true; connectButtonText.value = '前往蓝牙设置'; break; case ErrorType.noPermission: showRetryButton.value = true; retryButtonText.value = '授予权限'; break; case ErrorType.associationFailed: showRetryButton.value = true; retryButtonText.value = '重新关联'; break; default: showRetryButton.value = true; retryButtonText.value = '重试'; 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. 检查蓝牙状态 if (_bluetoothManager.bluetoothState == 'off') { _setError(ErrorType.bluetoothOff, '请开启蓝牙'); return; } // 2. 检查权限 if (!await _checkPermissions()) { _setError(ErrorType.noPermission, '请授予必要权限'); 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, '检查失败,请重试'); } } /// 检查权限 Future _checkPermissions() async { // Android权限检查 if (Platform.isAndroid) { // 检查蓝牙相关权限 final bluetoothScan = await Permission.bluetoothScan.request(); final bluetoothConnect = await Permission.bluetoothConnect.request(); final location = await Permission.locationWhenInUse.request(); return bluetoothScan.isGranted && bluetoothConnect.isGranted && location.isGranted; } return true; } /// 验证设备 Future _verifyDevice(BluetoothDevice device) async { try { Logger.i(_tag, '开始验证设备: ${device.name} (${device.address})'); // TODO: 实现API验证逻辑 // 暂时模拟验证通过 await Future.delayed(const Duration(seconds: 2)); // 检查设备名称是否包含 DeepSound 或 DeapSound final deviceName = device.name ?? ''; if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) { Logger.i(_tag, '设备验证通过'); _verifiedDeviceAddress = device.address; // 检查是否已有BLE关联 final pairedMacAddress = await _bleManager.getPairedMacAddress(); Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress'); if (pairedMacAddress != null && pairedMacAddress.toUpperCase() == device.address.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); } } else { _setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备'); } } catch (e) { Logger.e(_tag, '设备验证异常: $e'); _setError(ErrorType.networkError, '验证失败,请重试'); } } /// 开始设备关联 void _startDeviceAssociation() async { try { if (_verifiedDeviceAddress == null) { _setError(ErrorType.associationFailed, '设备地址无效'); return; } Logger.i(_tag, '开始BLE设备关联: $_verifiedDeviceAddress'); // 调用BLE管理器的关联方法 final success = await _bleManager.startDeviceAssociation( deviceNamePattern: 'DeapSound', // 或者使用 _currentClassicDevice?.name macAddress: _verifiedDeviceAddress!, ); if (success) { Logger.i(_tag, 'BLE设备关联成功'); // 关联成功后,转到等待BLE连接状态 _transition(PairingState.waitingBle); } else { _setError(ErrorType.associationFailed, 'BLE设备关联失败'); } } catch (e) { Logger.e(_tag, 'BLE设备关联异常: $e'); _setError(ErrorType.associationFailed, '设备关联失败,请重试'); } } /// 开始BLE连接 void _startBleConnection() async { try { // 设置超时定时器 _bleTimeoutTimer?.cancel(); _bleTimeoutTimer = Timer(const Duration(seconds: 30), () { if (_currentState.value == PairingState.waitingBle) { _setError(ErrorType.bleTimeout, '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, 'BLE配对启动失败'); } } } catch (e) { Logger.e(_tag, 'BLE连接失败: $e'); _setError(ErrorType.bleTimeout, 'BLE连接失败'); } } /// 导航到主页 void _navigateToHome() { Future.delayed(const Duration(seconds: 1), () { 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 onSkipTap() { Logger.i(_tag, '用户选择跳过配对'); 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'); } } }