import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'dart:async'; import '../../../data/services/novice_guide_service.dart'; import '../../../routes/app_routes.dart'; import '../../../core/utils/logger.dart'; import 'package:flutter/material.dart'; import '../../../data/services/bluetooth_manager.dart'; import '../../../data/services/ble_manager.dart'; import '../../ota_upgrade/controllers/ota_core_contropller.dart'; /// 连接状态枚举 enum ConnectionStatus { disconnected, // 未连接 connecting, // 连接中 connected, // 已连接 failed // 连接失败 } /// 主页控制器,管理设备连接状态和信息展示 class HomeController extends GetxController { static const String _tag = 'HomeCtrl'; static HomeController get to => Get.find(); final _isFullyConnected = false.obs; String? _lastConnectedDeviceName; // 添加电池信息定时刷新相关变量 Timer? _batteryRefreshTimer; static const Duration _batteryRefreshInterval = Duration(seconds: 2); // 2秒刷新一次 // 添加OTA升级检查相关变量 final _otaCoreService = OtaCoreService(); static bool _hasCheckedOta = false; // 防止重复检查 bool get isFullyConnected => _isFullyConnected.value; RxBool get isFullyConnectedRx => _isFullyConnected; BluetoothDevice? get currentDevice => _bluetoothManager.currentDevice; Rx get deviceInfo => _bleManager.deviceInfo; final leftEarBattery = 0.obs; final rightEarBattery = 0.obs; final caseBattery = 0.obs; final leftEarCharging = false.obs; final rightEarCharging = false.obs; final caseCharging = false.obs; final firmwareVersion = ''.obs; void updateDeviceInfo(DeviceInfo? newDeviceInfo) { leftEarBattery.value = newDeviceInfo?.leftEarBattery ?? 0; rightEarBattery.value = newDeviceInfo?.rightEarBattery ?? 0; caseBattery.value = newDeviceInfo?.caseBattery ?? 0; leftEarCharging.value = newDeviceInfo?.leftEarCharging ?? false; rightEarCharging.value = newDeviceInfo?.rightEarCharging ?? false; caseCharging.value = newDeviceInfo?.caseCharging ?? false; firmwareVersion.value = newDeviceInfo?.firmwareVersion ?? ''; } Worker? _deviceInfoWorker; Worker? _classicBluetoothWorker; Worker? _bleConnectionWorker; final _bluetoothManager = Get.find(); final _bleManager = Get.find(); final noviceGuideService = Get.find(); @override void onInit() { super.onInit(); _initWithCachedInfo(); _startBatteryRefreshTimer(); // 启动电池信息定时刷新 } @override void onClose() { _deviceInfoWorker?.dispose(); _classicBluetoothWorker?.dispose(); _bleConnectionWorker?.dispose(); _stopBatteryRefreshTimer(); // 停止定时器 super.onClose(); } void _initWithCachedInfo() { _setupStateListeners(); _checkConnectionStatus(); } void _setupStateListeners() { _deviceInfoWorker = ever(_bleManager.deviceInfo, (DeviceInfo? info) { if (info != null) { updateDeviceInfo(info); } update(); }); _classicBluetoothWorker = ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) { if (device != null) { _lastConnectedDeviceName = device.name; } _checkConnectionStatus(); }); _bleConnectionWorker = ever(_bleManager.connectionStateRx, (int state) { _checkConnectionStatus(); }); } Future refreshDeviceConnection() async { await _checkConnectionStatus(); // 如果设备已连接,立即刷新电池信息 if (_isFullyConnected.value) { await _refreshBatteryInfo(); } } void rescanDevices() { Get.toNamed(Routes.pairing); } void openTranslation() { Get.toNamed(Routes.translation); } void exploreAIFeatures() { Get.toNamed(Routes.agent); } Future _checkConnectionStatus() async { try { final currentBleState = await _bleManager.getConnectionState(); bool hasClassicBluetooth = currentDevice != null; bool hasBleConnection = currentBleState == 2; bool wasConnected = _isFullyConnected.value; bool isNowConnected = hasClassicBluetooth && hasBleConnection; if (isNowConnected && currentDevice == null) { isNowConnected = false; } if (_isFullyConnected.value != isNowConnected) { _isFullyConnected.value = isNowConnected; _isFullyConnected.refresh(); update(); if (!wasConnected && isNowConnected) { await _bleManager.fetchDeviceInfo(); // 连接成功后立即刷新一次电池信息 Future.delayed(const Duration(milliseconds: 500), () { _refreshBatteryInfo(); }); // 连接成功后检查OTA升级 Future.delayed(const Duration(seconds: 2), () { _checkOtaUpgrade(); }); } // 根据连接状态控制定时器 if (isNowConnected) { _startBatteryRefreshTimer(); // 连接时启动定时器 } else { _stopBatteryRefreshTimer(); // 断开时停止定时器 _hasCheckedOta = false; // 重置OTA检查状态 } } update(); } catch (e) { Logger.e(_tag, '${'checkConnectionStatusFailed'.tr}: $e'); if (_isFullyConnected.value) { _isFullyConnected.value = false; _isFullyConnected.refresh(); _stopBatteryRefreshTimer(); // 发生错误时停止定时器 _hasCheckedOta = false; // 重置OTA检查状态 update(); } } } Color getConnectionStatusColor() { return _isFullyConnected.value ? Colors.green : Colors.grey; } String getConnectionStatusText() { return _isFullyConnected.value ? 'connected'.tr : 'unconnected'.tr; } bool get shouldShowDeviceInfo => currentDevice != null; String getDeviceName() { if (_isFullyConnected.value && currentDevice == null) { _checkConnectionStatus(); } final deviceName = currentDevice?.name; if (deviceName != null && deviceName.isNotEmpty) { return deviceName; } final bleDeviceName = deviceInfo.value?.name; if (bleDeviceName != null && bleDeviceName.isNotEmpty) { return bleDeviceName; } if (!_isFullyConnected.value && _lastConnectedDeviceName != null && _lastConnectedDeviceName!.isNotEmpty) { return _lastConnectedDeviceName!; } return 'unknownEquipment'.tr; } String getSignalStrength() { if (!_isFullyConnected.value) { return 'zeroSignal'.tr; } final random = DateTime.now().millisecondsSinceEpoch % 3; switch (random) { case 0: return 'good'.tr; case 1: return 'fine'.tr; default: return 'excellent'.tr; } } String getDeviceId() { return deviceInfo.value?.address ?? currentDevice?.address ?? 'unknown'.tr; } String getBatteryText() { return deviceInfo.value?.batteryLevel != null && deviceInfo.value!.batteryLevel > 0 ? '${deviceInfo.value?.batteryLevel}%' : 'unknown'.tr; } String getEarbudsText() { if (deviceInfo.value == null || (deviceInfo.value!.leftEarBattery <= 0 && deviceInfo.value!.rightEarBattery <= 0 || deviceInfo.value!.caseBattery > 100)) { return 'unknown'.tr; } String leftStatus = deviceInfo.value!.leftEarBattery > 0 ? '${deviceInfo.value!.leftEarBattery}%' : 'N/A'; String rightStatus = deviceInfo.value!.rightEarBattery > 0 ? '${deviceInfo.value!.rightEarBattery}%' : 'N/A'; leftStatus = deviceInfo.value!.leftEarCharging ? '$leftStatus ⚡' : leftStatus; rightStatus = deviceInfo.value!.rightEarCharging ? '$rightStatus ⚡' : rightStatus; return '${'leftEar'.tr}: $leftStatus / ${'rightEar'.tr}: $rightStatus'; // 左耳: xxx / 右耳: xxx } String getCaseText() { if (deviceInfo.value == null || deviceInfo.value!.caseBattery <= 0 || deviceInfo.value!.caseBattery > 100) { return 'unknown'.tr; } String caseStatus = '${deviceInfo.value!.caseBattery}%'; if (deviceInfo.value!.caseCharging) { caseStatus = '$caseStatus ⚡'; } return '${'chargingCase'.tr}: $caseStatus'; // 充电仓: xxx } String getChargingText() { if (deviceInfo.value == null) { return 'unknown'.tr; } bool isCharging = deviceInfo.value!.leftEarCharging || deviceInfo.value!.rightEarCharging || deviceInfo.value!.caseCharging; return isCharging ? 'charging'.tr : 'notCharging'.tr; } String getVersionText() { return deviceInfo.value?.firmwareVersion.isNotEmpty == true ? deviceInfo.value!.firmwareVersion : 'unknown'.tr; } /// 启动电池信息定时刷新 void _startBatteryRefreshTimer() { _stopBatteryRefreshTimer(); // 先停止现有定时器 _batteryRefreshTimer = Timer.periodic(_batteryRefreshInterval, (timer) { // 只有在设备完全连接时才刷新电池信息 if (_isFullyConnected.value) { _refreshBatteryInfo(); } }); Logger.d(_tag, '电池信息定时刷新已启动,间隔: ${_batteryRefreshInterval.inSeconds}秒'); } /// 停止电池信息定时刷新 void _stopBatteryRefreshTimer() { if (_batteryRefreshTimer != null) { _batteryRefreshTimer!.cancel(); _batteryRefreshTimer = null; Logger.d(_tag, '电池信息定时刷新已停止'); } } /// 刷新电池信息 Future _refreshBatteryInfo() async { try { if (!_isFullyConnected.value) { return; } //Logger.d(_tag, '开始刷新电池信息...'); // 通过BLE管理器获取最新的电池信息 final success = await _bleManager.fetchBatteryInfo(); if (success) { //Logger.d(_tag, '电池信息刷新请求发送成功'); } else { //Logger.w(_tag, '电池信息刷新请求发送失败'); } } catch (e) { //Logger.e(_tag, '刷新电池信息时发生错误: $e'); } } /// 检查OTA固件升级 /// 在BLE连接成功后调用,检查是否需要升级 Future _checkOtaUpgrade() async { try { // 防止重复检查 if (_hasCheckedOta) { return; } Logger.d(_tag, '开始检查OTA固件升级...'); // 检查BLE连接状态 if (!_isFullyConnected.value) { Logger.d(_tag, '设备未完全连接,跳过OTA检查'); return; } // 获取当前版本信息 final currentInfo = await _otaCoreService.getCurrentVersionInfo(); final currentVersion = currentInfo['currentVersion'] as String; // 获取最新版本信息 final latestInfo = await _otaCoreService.getLatestVersionInfo(); final latestVersion = latestInfo['latestVersion'] as String; Logger.d(_tag, '当前版本: $currentVersion, 最新版本: $latestVersion'); // 检查是否有更新 final hasUpdate = _otaCoreService.isNewVersionAvailable(currentVersion, latestVersion); if (hasUpdate) { Logger.d(_tag, '发现新版本,显示升级提醒'); _showOtaUpgradeDialog( latestVersion, latestInfo['updateDescription'] as String?); } else { Logger.d(_tag, '当前已是最新版本'); } _hasCheckedOta = true; } catch (e) { Logger.e(_tag, '检查OTA升级失败: $e'); // 即使检查失败,也标记为已检查,避免重复尝试 _hasCheckedOta = true; } } /// 显示OTA升级提醒对话框 /// [latestVersion] 最新版本号 /// [updateDescription] 更新描述 void _showOtaUpgradeDialog(String latestVersion, String? updateDescription) { Get.dialog( AlertDialog( title: Row( children: [ Icon( Icons.headset, color: Colors.blue[600], size: 24.sp, ), SizedBox(width: 8.w), Text( 'ota_newVersionFound'.tr, style: TextStyle( color: Colors.blue[700], fontWeight: FontWeight.w600, ), ), ], ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${'latestFirmwareVersion'.tr}: $latestVersion', style: TextStyle( fontWeight: FontWeight.w500, fontSize: 16.sp, ), ), // if (updateDescription != null && updateDescription.isNotEmpty) // SizedBox(height: 8.sp), // if (updateDescription != null && updateDescription.isNotEmpty) // Text( // updateDescription, // style: TextStyle( // color: Colors.grey[600], // fontSize: 14.sp, // ), // ), // if (updateDescription != null && updateDescription.isNotEmpty) // SizedBox(height: 8.sp), // Text( // '建议及时升级以获得更好的使用体验', // style: TextStyle( // color: Colors.orange[700], // fontSize: 12.sp, // ), // ), ], ), actions: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // 稍后再说 (靠左) TextButton( onPressed: () { Logger.d(_tag, '用户取消OTA升级'); Get.back(); }, child: Text( 'talkLater'.tr, style: TextStyle(color: Colors.grey[600]), ), ), // 立即升级 (靠右) ElevatedButton( onPressed: () { Logger.d(_tag, '用户确认OTA升级,跳转到升级页面'); Get.back(); Get.toNamed(Routes.OTA_UPGRADE); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue[600], foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.sp), ), ), child: Text( 'ota_updateNow'.tr, style: TextStyle(fontSize: 14.sp), ), ), ], ), ], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.sp), ), backgroundColor: Colors.white, ), ); } }