import 'package:get/get.dart'; import '../../../core/routes/app_routes.dart'; import '../../../data/services/bluetooth_service.dart'; import '../../../core/utils/logger.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart' hide BluetoothService; import 'package:flutter/material.dart'; import '../../../data/services/voice_interaction_service.dart'; // 连接状态枚举 enum ConnectionStatus { disconnected, // 未连接 connecting, // 连接中 connected, // 已连接 failed // 连接失败 } class HomeController extends GetxController { static HomeController get to => Get.find(); // 设备连接状态 final _isConnected = false.obs; bool get isConnected => _isConnected.value; // 连接状态 final _connectionStatus = ConnectionStatus.disconnected.obs; ConnectionStatus get connectionStatus => _connectionStatus.value; // 电池状态 final _leftEarbudBattery = 75.obs; final _rightEarbudBattery = 52.obs; final _caseBattery = 92.obs; int get leftEarbudBattery => _leftEarbudBattery.value; int get rightEarbudBattery => _rightEarbudBattery.value; int get caseBattery => _caseBattery.value; // 固件版本 final String firmwareVersion = 'v2.4.1'; // 蓝牙设备信息 final _deviceInfo = {}.obs; Map get deviceInfo => _deviceInfo.value; // 蓝牙服务 BluetoothService? _bluetoothService; // 连接错误信息 final _connectionErrorMsg = ''.obs; String get connectionErrorMsg => _connectionErrorMsg.value; @override void onInit() { super.onInit(); // 立即加载缓存的设备信息并显示 _loadCachedDeviceInfo(); // 先进行简单初始化,避免立即进行蓝牙操作 _initBasicServices(); // 延迟初始化蓝牙相关功能,让UI先渲染完成 Future.delayed(const Duration(milliseconds: 1200), () { _initBluetoothService(); }); } // 立即加载缓存的设备信息 void _loadCachedDeviceInfo() { try { // 1. 首先检查是否有传入的设备信息(从PairingController传入) if (Get.arguments != null && Get.arguments is Map) { Logger.info('使用传入的设备信息'); _deviceInfo.assignAll(Get.arguments); _updateConnectionStatus(); update(); // 立即更新UI return; } // 2. 如果没有传入信息,尝试从BluetoothService获取上次连接的设备信息 if (Get.isRegistered()) { BluetoothService bluetoothService = Get.find(); if (bluetoothService.lastConnectedDeviceInfo.isNotEmpty) { Logger.info('使用BluetoothService中存储的上次连接设备信息'); _deviceInfo.assignAll(bluetoothService.lastConnectedDeviceInfo); _updateConnectionStatus(); update(); // 立即更新UI return; } } // 3. 如果上述都没有,显示未连接状态 Logger.info('没有找到缓存的设备信息,显示未连接状态'); _connectionStatus.value = ConnectionStatus.disconnected; _isConnected.value = false; update(); // 立即更新UI } catch (e) { Logger.error('加载缓存设备信息失败: $e'); } } // 基础服务初始化,不涉及蓝牙等耗时操作 void _initBasicServices() { try { // 初始化语音交互 Future.microtask(() => VoiceInteractionService.to.initialize()); // 检查是否有传入的蓝牙设备信息 if (Get.arguments != null && Get.arguments is Map) { _deviceInfo.assignAll(Get.arguments); _updateConnectionStatus(); } // 模拟电池状态更新(不涉及设备通信) _simulateBatteryUpdates(); } catch (e) { Logger.error('初始化基础服务失败: $e'); } } // 初始化蓝牙服务 void _initBluetoothService() { try { if (Get.isRegistered()) { _bluetoothService = Get.find(); // 不再重复加载设备信息,因为已经在_loadCachedDeviceInfo中加载过了 // 只进行状态同步 // 主动检查当前连接状态并更新 _checkAndUpdateCurrentConnectionState(); // 监听连接状态变化 ever(_bluetoothService!.connectionStateObs, (state) { Logger.info('蓝牙连接状态变化: $state'); _processConnectionStateChange(state); }); // 监听选中设备变化 ever(_bluetoothService!.selectedDeviceObs, (device) { Logger.info('蓝牙选中设备变化: ${device?.platformName ?? "无设备"}'); if (device != null) { _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _updateConnectionStatus(); // 通知UI刷新 update(); } else if (_isConnected.value) { // 如果设备断开连接,更新状态 _isConnected.value = false; // 不清除设备信息,以便可以显示上次连接的设备 _connectionStatus.value = ConnectionStatus.disconnected; // 通知UI刷新 update(); } }); // 监听最后连接的设备信息变化 ever(_bluetoothService!.lastConnectedDeviceInfoObs, (info) { Logger.info('最后连接的设备信息变化'); if (info.isNotEmpty) { // 只有当设备信息为空或者连接状态不是已连接时,才更新设备信息 if (_deviceInfo.isEmpty || _connectionStatus.value != ConnectionStatus.connected) { _deviceInfo.assignAll(info); _updateConnectionStatus(); // 通知UI刷新 update(); } } }); // 如果当前没有连接状态,但有设备信息,尝试在后台重新连接 if (_connectionStatus.value != ConnectionStatus.connected && _deviceInfo.isNotEmpty && _deviceInfo['device'] != null && _deviceInfo['device']['id'] != null) { // 延迟后台尝试连接设备,不阻塞UI Future.delayed(const Duration(milliseconds: 2000), () { _reconnectToLastDevice(); }); } // 如果没有设备信息,延迟尝试获取已配对设备 else if (_deviceInfo.isEmpty) { // 这个操作放在最后并延迟执行,因为它可能会触发蓝牙扫描 Future.delayed(const Duration(milliseconds: 2500), () { _checkPairedDevices(); }); } } } catch (e) { Logger.error('获取蓝牙服务失败: $e'); _connectionErrorMsg.value = '获取蓝牙服务失败'; // 通知UI刷新 update(); } } // 检查并更新当前连接状态 void _checkAndUpdateCurrentConnectionState() { if (_bluetoothService != null && _bluetoothService!.selectedDevice != null) { // 如果有选择的设备,使用可靠方法获取一次状态 _bluetoothService!.getReliableConnectionState(_bluetoothService!.selectedDevice!).then((state) { Logger.info('主动检查设备连接状态: $state'); _processConnectionStateChange(state); }).catchError((e) { Logger.error('检查连接状态失败: $e'); }); } } // 后台尝试重新连接到上次的设备 Future _reconnectToLastDevice() async { try { Logger.info('尝试重新连接到上次的设备'); _connectionStatus.value = ConnectionStatus.connecting; update(); // 立即更新UI显示连接中状态 // 使用超时机制,防止无响应 return await Future.sync(() async { // 获取设备ID String deviceId = _deviceInfo['device']['id']; Logger.info('上次连接的设备ID: $deviceId'); // 获取已配对设备,使用超时保护 Logger.info('开始获取系统已配对设备列表...'); List pairedDevices = await _bluetoothService!.getPairedDevices() .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('获取已配对设备超时'); return []; }); // 记录配对设备 if (pairedDevices.isNotEmpty) { Logger.info('发现 ${pairedDevices.length} 个已配对设备:'); for (var i = 0; i < pairedDevices.length; i++) { Logger.info('配对设备 #$i: ${pairedDevices[i].platformName ?? "未命名设备"} (${pairedDevices[i].remoteId.str})'); } } else { Logger.info('未找到任何已配对设备'); } // 查找匹配ID的设备 Logger.info('开始查找匹配ID的设备: $deviceId'); BluetoothDevice? targetDevice; for (var device in pairedDevices) { Logger.info('检查设备 ${device.platformName ?? "未命名设备"} (${device.remoteId.str}) 是否匹配'); if (device.remoteId.str == deviceId) { Logger.info('找到匹配ID的设备: ${device.platformName ?? "未命名设备"}'); targetDevice = device; break; } } // 如果找到目标设备,尝试连接 if (targetDevice != null) { Logger.info('找到目标设备: ${targetDevice.platformName ?? "未命名设备"},尝试连接'); // 直接尝试连接设备,不做复杂状态检查 Logger.info('开始连接设备 ${targetDevice?.platformName ?? "未命名设备"}'); final success = await _bluetoothService!.connectToDevice(targetDevice) .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('连接设备 ${targetDevice?.platformName ?? "未命名设备"} 超时'); return false; }); if (success) { Logger.info('重新连接到设备 ${targetDevice?.platformName ?? "未命名设备"} 成功'); _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _connectionStatus.value = ConnectionStatus.connected; _isConnected.value = true; _updateConnectionStatus(); update(); // 立即更新UI } else { Logger.error('重新连接到设备 ${targetDevice?.platformName ?? "未命名设备"} 失败'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '重新连接设备失败,请手动刷新或重新连接'; update(); // 立即更新UI } } else { Logger.info('未找到匹配ID的设备,尝试连接第一个配对设备'); // 如果没有找到目标设备但有其他配对设备,尝试连接第一个 if (pairedDevices.isNotEmpty) { var firstDevice = pairedDevices.first; Logger.info('尝试连接第一个配对设备: ${firstDevice.platformName ?? "未命名设备"}'); // 直接尝试连接设备 Logger.info('开始连接设备 ${firstDevice.platformName ?? "未命名设备"}'); final success = await _bluetoothService!.connectToDevice(firstDevice) .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('连接设备 ${firstDevice.platformName ?? "未命名设备"} 超时'); return false; }); if (success) { Logger.info('自动连接到已配对设备成功: ${firstDevice.platformName ?? "未命名设备"}'); _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _connectionStatus.value = ConnectionStatus.connected; _isConnected.value = true; // 直接设置连接状态 _updateConnectionStatus(); update(); // 立即更新UI } else { Logger.error('连接到第一个配对设备 ${firstDevice.platformName ?? "未命名设备"} 失败'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '连接设备失败,请重试'; update(); // 立即更新UI } } else { Logger.info('没有找到任何可用的配对设备'); _connectionStatus.value = ConnectionStatus.disconnected; update(); // 立即更新UI } } }).timeout(const Duration(seconds: 15), onTimeout: () { Logger.error('重新连接设备整体流程超时'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '连接超时,请手动刷新或重新连接'; update(); // 立即更新UI }); } catch (e) { Logger.error('重新连接到设备失败: $e'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '连接失败,请手动刷新或重新连接'; update(); // 立即更新UI } } // 处理连接状态变化 void _processConnectionStateChange(BluetoothConnectionState state) { // 强制从蓝牙服务获取最新设备信息 _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); switch (state) { case BluetoothConnectionState.connected: _connectionStatus.value = ConnectionStatus.connected; _connectionErrorMsg.value = ''; _isConnected.value = true; // 直接设置连接状态为true // _showConnectionSuccessMessage(); break; case BluetoothConnectionState.disconnected: _connectionStatus.value = ConnectionStatus.disconnected; _isConnected.value = false; // 直接设置连接状态为false break; case BluetoothConnectionState.connecting: _connectionStatus.value = ConnectionStatus.connecting; break; default: // 其他状态暂不处理 break; } // 延迟一帧后刷新状态,确保UI能更新 Future.microtask(() => _updateConnectionStatus()); // 通知UI刷新 update(); } // 显示连接成功消息 void _showConnectionSuccessMessage() { if (_bluetoothService?.selectedDevice != null) { String deviceName = _bluetoothService!.selectedDevice!.platformName.isEmpty ? '未命名设备' : _bluetoothService!.selectedDevice!.platformName; Get.snackbar( '连接成功', '已成功连接到设备: $deviceName', snackPosition: SnackPosition.TOP, backgroundColor: Colors.green[100], colorText: Colors.green[800], duration: const Duration(seconds: 2), ); } } // 尝试查找并连接已配对设备 Future _checkPairedDevices() async { try { if (_bluetoothService != null) { Logger.info('开始检查已配对设备流程'); // 更新状态为正在连接 _connectionStatus.value = ConnectionStatus.connecting; update(); // 立即更新UI // 如果已有选中的设备并且已连接,直接使用 if (_bluetoothService!.selectedDevice != null && _bluetoothService!.connectionState == BluetoothConnectionState.connected) { Logger.info('使用已连接的设备: ${_bluetoothService!.selectedDevice!.platformName}, 连接状态: ${_bluetoothService!.connectionState}'); _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _connectionStatus.value = ConnectionStatus.connected; _isConnected.value = true; // 直接设置连接状态 _updateConnectionStatus(); update(); // 立即更新UI return; } // 获取已配对设备 Logger.info('开始获取系统已配对设备列表...'); final pairedDevices = await _bluetoothService!.getPairedDevices() .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('获取已配对设备超时'); return []; }); if (pairedDevices.isEmpty) { Logger.info('没有找到已配对设备'); _connectionStatus.value = ConnectionStatus.disconnected; update(); // 立即更新UI return; } Logger.info('发现 ${pairedDevices.length} 个已配对设备'); for (var i = 0; i < pairedDevices.length; i++) { var device = pairedDevices[i]; Logger.info('已配对设备 #$i: ${device.platformName} (${device.remoteId.str})'); } // 遍历配对设备,检查是否有需要连接的设备 Logger.info('开始查找设备进行连接...'); if (pairedDevices.isNotEmpty) { // 选择第一个配对设备进行连接 var deviceToConnect = pairedDevices.first; Logger.info('尝试连接配对设备: ${deviceToConnect.platformName ?? "未命名设备"}'); final success = await _bluetoothService!.connectToDevice(deviceToConnect) .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('连接设备 ${deviceToConnect.platformName ?? "未命名设备"} 超时'); return false; }); if (success) { Logger.info('成功连接到设备: ${deviceToConnect.platformName ?? "未命名设备"}'); _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _connectionStatus.value = ConnectionStatus.connected; _isConnected.value = true; _updateConnectionStatus(); update(); // 立即更新UI } else { // 连接失败 Logger.error('连接设备 ${deviceToConnect.platformName ?? "未命名设备"} 失败'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '连接设备失败,请重试'; update(); // 立即更新UI } } else { _connectionStatus.value = ConnectionStatus.disconnected; update(); // 立即更新UI } } } catch (e) { Logger.error('检查已配对设备失败: $e'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '检查设备失败: ${e.toString()}'; update(); // 立即更新UI } } // 更新连接状态 void _updateConnectionStatus() { if (_deviceInfo.containsKey('connected')) { _isConnected.value = _deviceInfo['connected'] ?? false; // 如果设备信息显示已连接,但状态不是已连接,则更新状态 if (_isConnected.value && _connectionStatus.value != ConnectionStatus.connected) { _connectionStatus.value = ConnectionStatus.connected; } else if (!_isConnected.value && _connectionStatus.value == ConnectionStatus.connected) { // 如果设备显示未连接,但状态是已连接,则更新状态 _connectionStatus.value = ConnectionStatus.disconnected; } } else { _isConnected.value = false; if (_connectionStatus.value == ConnectionStatus.connected) { _connectionStatus.value = ConnectionStatus.disconnected; } } } // 模拟电池状态更新 void _simulateBatteryUpdates() { // 在实际应用中,这里应该从设备获取真实的电池状态 // 这里只是模拟随机波动 } // 探索AI功能 void exploreAIFeatures() { Get.toNamed(Routes.explore); } // 更新固件 void updateFirmware() { Get.snackbar( '提示', '开始下载固件更新...', snackPosition: SnackPosition.TOP, ); // 模拟更新过程 // 在真实应用中,这里应该有固件更新的实际逻辑 } // 打开降噪功能 void toggleNoiseReduction() { Get.snackbar( '提示', '降噪功能已开启', snackPosition: SnackPosition.TOP, ); } // 音效设置 void openSoundEffects() { Get.snackbar( '提示', '音效设置功能尚未实现', snackPosition: SnackPosition.TOP, ); } // 环境音功能 void toggleAmbientSound() { Get.snackbar( '提示', '环境音模式已开启', snackPosition: SnackPosition.TOP, ); } // 收藏的设置 void openFavorites() { Get.snackbar( '提示', '收藏功能尚未实现', snackPosition: SnackPosition.TOP, ); } // 打开设置页面 void openSettings() { Get.toNamed(Routes.settings); } // 重新扫描设备 void rescanDevices() { if (_bluetoothService != null) { Get.toNamed(Routes.pairing); } else { Get.snackbar( '提示', '蓝牙服务不可用', snackPosition: SnackPosition.TOP, ); } } // 获取设备名称 String getDeviceName() { if (_deviceInfo.isEmpty || _deviceInfo['device'] == null) { return '未连接设备'; } final device = _deviceInfo['device'] as Map; return device['name'] ?? '未命名设备'; } // 获取设备ID String getDeviceId() { if (_deviceInfo.isEmpty || _deviceInfo['device'] == null) { return ''; } final device = _deviceInfo['device'] as Map; return device['id'] ?? ''; } // 获取设备信号强度 String getSignalStrength() { if (_deviceInfo.isEmpty || _deviceInfo['device'] == null) { return '无信号'; } final device = _deviceInfo['device'] as Map; final rssi = device['rssi']; if (rssi == null) { return '未知'; } // RSSI通常在-100到0之间,值越大信号越强 if (rssi > -60) { return '强'; } else if (rssi > -80) { return '中'; } else { return '弱'; } } // 刷新设备信息 Future refreshDeviceInfo() async { try { // 检查蓝牙是否可用 if (_bluetoothService == null) { Get.snackbar( '提示', '蓝牙服务不可用', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red[100], colorText: Colors.red[800], ); return; } // 设置正在刷新状态,但保留当前设备信息显示 _connectionStatus.value = ConnectionStatus.connecting; update(); // 立即更新UI状态 // 强制检查当前蓝牙连接状态 _checkAndUpdateCurrentConnectionState(); if (_bluetoothService!.selectedDevice != null) { // 如果有选中的设备,刷新设备信息 _deviceInfo.assignAll(_bluetoothService!.getConnectedDeviceInfo()); _updateConnectionStatus(); update(); // 确保UI更新 // 检查刷新后的连接状态 if (_isConnected.value) { Get.snackbar( '提示', '设备信息已更新', snackPosition: SnackPosition.TOP, backgroundColor: Colors.green[100], colorText: Colors.green[800], ); } else { // 设备可能已断开连接,尝试使用存储的设备信息重新连接 if (_bluetoothService!.lastConnectedDeviceInfo.isNotEmpty) { _connectionStatus.value = ConnectionStatus.disconnected; update(); // 更新状态 _reconnectToLastDevice(); } else { // 上次连接的设备信息也为空,尝试连接已配对设备 await _checkPairedDevices(); } } } else if (_bluetoothService!.lastConnectedDeviceInfo.isNotEmpty) { // 如果没有选中的设备但有上次连接的设备信息,尝试重新连接 _deviceInfo.assignAll(_bluetoothService!.lastConnectedDeviceInfo); _updateConnectionStatus(); update(); // 确保UI更新 _reconnectToLastDevice(); } else { // 如果没有选中的设备,尝试连接已配对设备 await _checkPairedDevices(); if (_connectionStatus.value == ConnectionStatus.failed) { Get.snackbar( '提示', _connectionErrorMsg.value.isNotEmpty ? _connectionErrorMsg.value : '连接设备失败', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red[100], colorText: Colors.red[800], ); } else if (_connectionStatus.value == ConnectionStatus.disconnected) { Get.snackbar( '提示', '未找到已连接设备,请连接设备', snackPosition: SnackPosition.TOP, backgroundColor: Colors.amber[100], colorText: Colors.amber[800], ); } } } catch (e) { Logger.error('刷新设备信息失败: $e'); _connectionStatus.value = ConnectionStatus.failed; _connectionErrorMsg.value = '刷新设备信息失败: ${e.toString()}'; update(); // 确保状态更新 Get.snackbar( '提示', '刷新设备信息失败', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red[100], colorText: Colors.red[800], ); } } // 处理连接失败 String getConnectionStatusText() { switch (_connectionStatus.value) { case ConnectionStatus.connected: return "已连接"; case ConnectionStatus.connecting: return "连接中..."; case ConnectionStatus.disconnected: return "未连接"; case ConnectionStatus.failed: return "连接失败"; } } // 获取连接状态颜色 Color getConnectionStatusColor() { switch (_connectionStatus.value) { case ConnectionStatus.connected: return Colors.green; case ConnectionStatus.connecting: return Colors.blue; case ConnectionStatus.disconnected: return Colors.red; case ConnectionStatus.failed: return Colors.red; } } }