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 'package:classic_bluetooth/classic_bluetooth.dart' show BluetoothDevice; import '../../../data/services/ble_manager.dart'; import 'package:agent_service/agent_service.dart'; import 'package:ble_service/ble_service.dart'; /// 配对控制器,负责检查蓝牙权限、状态,并处理配对流程 class PairingController extends GetxController { static PairingController get to => Get.find(); // 状态标志 final isLoading = false.obs; // 权限是否已授予 final _hasPermissions = false.obs; bool get hasPermissions => _hasPermissions.value; // 蓝牙状态 final _bluetoothState = 'unknown'.obs; String get bluetoothState => _bluetoothState.value; bool get isBluetoothOn => _bluetoothState.value == 'on'; // 状态描述(用于UI显示) final statusDescription = 'initializing'.tr.obs; // 是否正在跳转到主页 bool _isNavigatingToHome = false; // 是否正在执行Companion关联流程 bool _isAssociating = false; // 当前连接设备信息 BluetoothDevice? get currentDevice => _bluetoothService.currentDevice; // 是否已连接设备 bool get isDeviceConnected => currentDevice != null; // 是否已完成Companion关联 final _companionAssociated = false.obs; bool get isCompanionAssociated => _companionAssociated.value; // 服务状态监听 Worker? _bluetoothStateWorker; Worker? _deviceWorker; // 蓝牙服务 final _bluetoothService = Get.find(); // BLE服务 final _bleService = BleService(); @override void onInit() { super.onInit(); _initialize(); } @override void onClose() { _bluetoothStateWorker?.dispose(); _deviceWorker?.dispose(); super.onClose(); } /// 初始化流程 Future _initialize() async { try { isLoading.value = true; statusDescription.value = 'checkingPermissions'.tr; // 检查并请求权限 if (!await _checkAndRequestPermissions()) { statusDescription.value = 'permissionDenied'.tr; return; } // 设置服务状态监听 _setupServiceStateListeners(); // 检查蓝牙状态 statusDescription.value = 'checkingBluetoothStatus'.tr; final isEnabled = await _bluetoothService.isBluetoothEnabled(); _bluetoothState.value = isEnabled ? 'on' : 'off'; if (!isEnabled) { statusDescription.value = 'bluetoothTurnedOff'.tr; return; } // 刷新已连接设备 statusDescription.value = 'searchingDevice'.tr; await refreshConnectedDevices(); // 检查是否已存在Companion设备关联,但不要重复调用关联流程 await _checkExistingCompanionAssociation(); } catch (e) { Logger.error('初始化配对控制器失败: $e'); statusDescription.value = 'initializationFailure'.tr; } finally { isLoading.value = false; _updateStatusDescription(); } } /// 检查是否已存在Companion设备关联 Future _checkExistingCompanionAssociation() async { // 只在Android平台执行 if (!Platform.isAndroid) return; try { final isSupported = await _bleService.isCompanionSupported(); if (!isSupported) return; final pairedMac = await _bleService.getPairedMacAddress(); if (pairedMac != null) { Logger.info('发现已关联的Companion设备: $pairedMac'); _companionAssociated.value = true; await _bleService.registerBackgroundScan(); } } catch (e) { Logger.error('检查现有Companion关联失败: $e'); } } /// 检查并请求必要的蓝牙权限 Future _checkAndRequestPermissions() async { Map statuses; List permissionsToRequest = []; if (Platform.isAndroid) { // Android 12+ (SDK 31+) 需要 SCAN 和 CONNECT // Android 6+ (SDK 23+) 需要 LOCATION permissionsToRequest.add(Permission.locationWhenInUse); // 基本定位权限 permissionsToRequest.add(Permission.microphone); // Android 12及以上版本才需要请求蓝牙扫描和连接权限 if (await _getAndroidSdkVersion() >= 31) { permissionsToRequest.add(Permission.bluetoothScan); permissionsToRequest.add(Permission.bluetoothConnect); } } else if (Platform.isIOS) { permissionsToRequest.add(Permission.bluetooth); } statuses = await permissionsToRequest.request(); bool allGranted = true; statuses.forEach((permission, status) { if (!status.isGranted) { allGranted = false; Logger.warning('权限 ${permission.toString()} 未被授予: $status'); } }); _hasPermissions.value = allGranted; return allGranted; } // 辅助方法获取Android SDK版本 Future _getAndroidSdkVersion() async { if (Platform.isAndroid) { // 这里需要原生代码支持来获取确切的SDK版本, // 或者使用 device_info_plus 插件 // 暂时返回一个较高值以触发新权限请求 return 31; // 假设运行在需要新权限的设备上 } return 0; } /// 设置服务状态监听 void _setupServiceStateListeners() { // 监听蓝牙服务的蓝牙状态变化 _bluetoothStateWorker = ever(_bluetoothService.bluetoothState.obs, (String state) { _bluetoothState.value = state; _updateStatusDescription(); // 如果蓝牙关闭,可能需要更新UI或提示用户 if (state == 'off') { Logger.info('蓝牙已关闭'); } }); Logger.info('liwei----------------- _setupServiceStateListeners 1'); // 监听当前设备变化 - 使用公开的currentDeviceRx字段 _deviceWorker = ever(_bluetoothService.currentDeviceRx, (BluetoothDevice? device) { if (device != null && !_isNavigatingToHome) { Logger.info('配对页面发现设备已连接: ${device.name}'); Logger.info('liwei----------------- _setupServiceStateListeners 2'); // 当经典蓝牙设备连接成功,尝试进行Companion关联 _handleDeviceConnected(); } _updateStatusDescription(); }); } /// 处理设备连接成功事件 Future _handleDeviceConnected() async { Logger.info('liwei----------------- _handleDeviceConnected 1'); if (!isDeviceConnected || _isNavigatingToHome) return; Logger.info('liwei----------------- _handleDeviceConnected 2'); // 如果已经完成关联,直接跳转 if (_companionAssociated.value) { _autoNavigateToHome(); return; } Logger.info('liwei----------------- _handleDeviceConnected 3'); // 启动关联流程 _startCompanionAssociation(); } /// 更新状态描述 void _updateStatusDescription() { if (!hasPermissions) { statusDescription.value = 'permissionDenied'.tr; return; } if (bluetoothState == 'off') { statusDescription.value = 'bluetoothTurnedOff'.tr; return; } if (isDeviceConnected) { if (Platform.isAndroid && !isCompanionAssociated && _isAssociating) { statusDescription.value = '${'associatingDevice'.tr} ${currentDevice!.name}'; } else if (isCompanionAssociated) { statusDescription.value = '${'connectedDevice'.tr} ${currentDevice!.name}'; } else { statusDescription.value = '${'connectedDevice'.tr} ${currentDevice!.name}'; } return; } if (isLoading.value) { statusDescription.value = 'searchingDevice'.tr; return; } statusDescription.value = 'notFound'.tr; } /// 刷新已连接设备 Future refreshConnectedDevices() async { if (!hasPermissions) { statusDescription.value = 'permissionDenied'.tr; return; } try { isLoading.value = true; statusDescription.value = 'searchingDevice'.tr; // 使用蓝牙服务刷新连接 await _bluetoothService.refreshDeviceConnection(); // 检查连接状态 if (isDeviceConnected) { Logger.info('刷新发现设备已连接: ${currentDevice!.name}'); // 当发现设备已连接,统一由_handleDeviceConnected处理 _handleDeviceConnected(); } else { Logger.info('刷新未发现已连接设备'); } } catch (e) { Logger.error('刷新设备失败: $e'); statusDescription.value = 'failedRefreshDevice'.tr; } finally { isLoading.value = false; _updateStatusDescription(); } } /// 启动Companion设备关联流程 Future _startCompanionAssociation() async { Logger.info('liwei----------------- _startCompanionAssociation 1'); // 如果不是Android平台,已经跳转到首页,已经完成关联或正在进行关联,直接返回 if (!Platform.isAndroid || _isNavigatingToHome || _companionAssociated.value || _isAssociating) { return; } Logger.info('liwei----------------- _startCompanionAssociation 2'); // 设置关联状态标志 _isAssociating = true; _updateStatusDescription(); try { // 检查是否支持Companion Device功能 final isSupported = await _bleService.isCompanionSupported(); if (!isSupported) { Logger.info('设备不支持Companion Device功能,跳过关联'); _companionAssociated.value = true; // 标记为已完成 _autoNavigateToHome(); return; } Logger.info('liwei----------------- _startCompanionAssociation 3'); // 检查是否已有配对的MAC地址 final pairedMac = await _bleService.getPairedMacAddress(); if (pairedMac != null) { // 已有关联的设备,检查是否与当前连接的设备一致 if (currentDevice?.address == pairedMac) { Logger.info('已关联的Companion设备与当前连接的设备一致'); _companionAssociated.value = true; await _bleService.registerBackgroundScan(); // _autoNavigateToHome(); // return; } else { // 不一致,清除旧关联 Logger.info('已关联的Companion设备与当前连接的设备不一致,清除旧关联'); await _bleService.clearAssociations(); } } Logger.info('liwei----------------- _startCompanionAssociation 4'); // 开始关联流程 if (currentDevice != null) { Logger.info('开始Companion设备关联流程, 设备MAC: ${currentDevice!.address}'); var success = await _bleService.startDeviceAssociation( deviceNamePattern: currentDevice!.name, macAddress: currentDevice!.address, ); success = true; if (success) { Logger.info('Companion设备关联成功'); _companionAssociated.value = true; // 注册后台扫描,确保应用被杀死后仍能被唤醒 await _bleService.registerBackgroundScan( macAddress: currentDevice!.address); Logger.info('liwei----------------- _startCompanionAssociation 5'); // 启动BLE后台服务(可选) await _startAgentService(); // 关联和后台扫描都成功后,再跳转 _autoNavigateToHome(); } else { Logger.error('Companion设备关联失败'); // 关联失败,但仍然可以跳转到主页(用户体验考虑) _autoNavigateToHome(); } } } catch (e) { Logger.error('Companion设备关联过程发生错误: $e'); // 出错时仍可以跳转主页 _autoNavigateToHome(); } finally { // 无论成功失败,都重置关联状态标志 _isAssociating = false; _updateStatusDescription(); } } /// 自动跳转到主页 Future _autoNavigateToHome() async { if (_isNavigatingToHome) return; // 如果没有连接,不进行跳转 if (!isDeviceConnected) return; // 在Android平台上,如果支持Companion且仍在关联中,不跳转 if (Platform.isAndroid) { final isSupported = await _bleService.isCompanionSupported(); if (isSupported && !isCompanionAssociated && _isAssociating) { Logger.info('等待Companion设备关联完成后再跳转'); return; } } _isNavigatingToHome = true; Logger.info('已找到连接的设备 ${currentDevice!.name},自动跳转到主页'); Future.delayed(const Duration(milliseconds: 500), () { Get.offAllNamed(Routes.home); }); } /// 启动BLE后台服务 Future _startAgentService() async { try { if (!isDeviceConnected) return; // 启动BLE服务,无需传递配置参数,将从.env读取 final result = await BleManager.to.startAgentService(); if (result) { Logger.info('BLE后台服务启动成功'); } else { Logger.error('BLE后台服务启动失败'); } } catch (e) { Logger.error('启动BLE后台服务发生错误: $e'); } } /// 停止BLE后台服务 Future _stopAgentService() async { try { final result = await BleManager.to.stopAgentService(); if (result) { Logger.info('BLE后台服务停止成功'); } else { Logger.error('BLE后台服务停止失败'); } } catch (e) { Logger.error('停止BLE后台服务发生错误: $e'); } } /// 打开系统蓝牙设置 void openBluetoothSettings() { try { if (!hasPermissions) { openAppSettings(); } else if (Platform.isAndroid && !isBluetoothOn) { AppSettings.openAppSettings(type: AppSettingsType.bluetooth); } else if (Platform.isIOS) { openAppSettings(); } else { AppSettings.openAppSettings(type: AppSettingsType.bluetooth); } } catch (e) { Logger.error('打开设置失败: $e'); } } /// 打开应用设置 Future openAppSettings() async { await AppSettings.openAppSettings(); } /// 跳过连接 void skipConnecting() { _isNavigatingToHome = true; Get.offAllNamed(Routes.home); } }