diff --git a/lib/core/bindings/initial_binding.dart b/lib/core/bindings/initial_binding.dart index a208349f0..7354a5dc7 100644 --- a/lib/core/bindings/initial_binding.dart +++ b/lib/core/bindings/initial_binding.dart @@ -20,6 +20,7 @@ import '../../data/services/bluetooth_manager.dart'; import '../../data/services/ble_manager.dart'; import '../../data/services/account_service.dart'; import '../../data/services/version_update_service.dart'; +import '../../data/services/ota_check_service.dart'; /// 初始绑定,用于管理全局依赖 class InitialBinding extends Bindings { @@ -80,6 +81,9 @@ class InitialBinding extends Bindings { // 新手引导 Get.lazyPut(() => NoviceGuideService(), fenix: true); + // OTA检查服务 + Get.lazyPut(() => OtaCheckService(), fenix: true); + // 杰理蓝牙服务 // // 语言管理器(需要最先初始化) diff --git a/lib/data/services/ota_check_service.dart b/lib/data/services/ota_check_service.dart new file mode 100644 index 000000000..12dad5451 --- /dev/null +++ b/lib/data/services/ota_check_service.dart @@ -0,0 +1,219 @@ +import 'package:get/get.dart'; +import '../../core/utils/logger.dart'; +import '../../routes/app_routes.dart'; +import '../../modules/ota_upgrade/controllers/ota_core_contropller.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +/// OTA检查服务 +/// 负责管理全局OTA检查状态,确保在应用生命周期内只检查一次 +class OtaCheckService extends GetxService { + static const String _tag = 'OtaCheckService'; + + // 全局状态管理 + static bool _hasCheckedInCurrentSession = false; + static bool _isCheckingInProgress = false; + + final _otaCoreService = OtaCoreService(); + + /// 获取服务实例 + static OtaCheckService get to => Get.find(); + + @override + void onInit() { + super.onInit(); + Logger.d(_tag, 'OTA检查服务已初始化'); + } + + /// 重置检查状态(仅在应用重启时调用) + static void resetCheckStatus() { + _hasCheckedInCurrentSession = false; + _isCheckingInProgress = false; + Logger.d(_tag, 'OTA检查状态已重置'); + } + + /// 检查是否应该进行OTA检查 + bool shouldCheckOta() { + return !_hasCheckedInCurrentSession && !_isCheckingInProgress; + } + + /// 标记为已检查 + void _markAsChecked() { + _hasCheckedInCurrentSession = true; + _isCheckingInProgress = false; + Logger.d(_tag, 'OTA检查状态已标记为完成'); + } + + /// 检查当前是否在Home页面 + bool _isCurrentlyOnHomePage() { + final currentRoute = Get.currentRoute; + final isOnHome = currentRoute == Routes.home || currentRoute == Routes.initial; + Logger.d(_tag, '当前路由: $currentRoute, 是否在Home页面: $isOnHome'); + return isOnHome; + } + + /// 执行OTA升级检查 + /// [isFullyConnected] 设备是否完全连接 + /// 返回是否成功执行了检查 + Future performOtaCheck(bool isFullyConnected) async { + try { + // 检查是否应该进行OTA检查 + if (!shouldCheckOta()) { + Logger.d(_tag, '跳过OTA检查 - 已检查过或正在检查中'); + return false; + } + + // 检查设备连接状态 + if (!isFullyConnected) { + Logger.d(_tag, '设备未完全连接,跳过OTA检查'); + return false; + } + + // 检查当前页面 + if (!_isCurrentlyOnHomePage()) { + Logger.d(_tag, '当前不在Home页面,跳过OTA检查'); + return false; + } + + // 标记为检查中 + _isCheckingInProgress = true; + Logger.d(_tag, '开始执行OTA固件升级检查...'); + + // 获取当前版本信息 + 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, '发现新版本,准备显示升级提醒'); + + // 再次确认当前在Home页面(防止异步执行期间页面切换) + if (_isCurrentlyOnHomePage()) { + _showOtaUpgradeDialog(latestVersion, latestInfo['updateDescription'] as String?); + } else { + Logger.d(_tag, '检查完成时已不在Home页面,取消显示弹窗'); + } + } else { + Logger.d(_tag, '当前已是最新版本'); + } + + // 标记为已检查(无论是否有更新都标记为已检查) + _markAsChecked(); + return true; + + } catch (e) { + Logger.e(_tag, '检查OTA升级失败: $e'); + // 即使检查失败,也标记为已检查,避免重复尝试 + _markAsChecked(); + return false; + } + } + + /// 显示OTA升级提醒对话框 + /// [latestVersion] 最新版本号 + /// [updateDescription] 更新描述 + void _showOtaUpgradeDialog(String latestVersion, String? updateDescription) { + // 最后一次确认当前页面状态 + if (!_isCurrentlyOnHomePage()) { + Logger.d(_tag, '显示弹窗时发现不在Home页面,取消显示'); + return; + } + + Logger.d(_tag, '显示OTA升级提醒对话框'); + + 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, + ), + ), + ], + ), + 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, + ), + barrierDismissible: true, // 允许点击外部关闭 + ); + } + + /// 获取当前检查状态(用于调试) + Map getCheckStatus() { + return { + 'hasCheckedInCurrentSession': _hasCheckedInCurrentSession, + 'isCheckingInProgress': _isCheckingInProgress, + 'currentRoute': Get.currentRoute, + 'isOnHomePage': _isCurrentlyOnHomePage(), + }; + } +} diff --git a/lib/modules/home/controllers/home_controller.dart b/lib/modules/home/controllers/home_controller.dart index 68c70b643..c3fa87398 100644 --- a/lib/modules/home/controllers/home_controller.dart +++ b/lib/modules/home/controllers/home_controller.dart @@ -1,4 +1,4 @@ -import 'package:flutter_screenutil/flutter_screenutil.dart'; + import 'package:get/get.dart'; import 'dart:async'; import '../../../data/services/novice_guide_service.dart'; @@ -7,7 +7,7 @@ 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'; +import '../../../data/services/ota_check_service.dart'; /// 连接状态枚举 enum ConnectionStatus { @@ -30,9 +30,8 @@ class HomeController extends GetxController { static const Duration _batteryRefreshInterval = Duration(seconds: 2); // 2秒刷新一次 - // 添加OTA升级检查相关变量 - final _otaCoreService = OtaCoreService(); - static bool _hasCheckedOta = false; // 防止重复检查 + // OTA检查服务 + late final OtaCheckService _otaCheckService; bool get isFullyConnected => _isFullyConnected.value; RxBool get isFullyConnectedRx => _isFullyConnected; @@ -68,6 +67,7 @@ class HomeController extends GetxController { @override void onInit() { super.onInit(); + _otaCheckService = Get.find(); _initWithCachedInfo(); _startBatteryRefreshTimer(); // 启动电池信息定时刷新 } @@ -162,7 +162,7 @@ class HomeController extends GetxController { _startBatteryRefreshTimer(); // 连接时启动定时器 } else { _stopBatteryRefreshTimer(); // 断开时停止定时器 - _hasCheckedOta = false; // 重置OTA检查状态 + // 注意:不再重置OTA检查状态,因为现在由全局服务管理 } } @@ -173,7 +173,7 @@ class HomeController extends GetxController { _isFullyConnected.value = false; _isFullyConnected.refresh(); _stopBatteryRefreshTimer(); // 发生错误时停止定时器 - _hasCheckedOta = false; // 重置OTA检查状态 + // 注意:不再重置OTA检查状态,因为现在由全局服务管理 update(); } } @@ -344,147 +344,27 @@ class HomeController extends GetxController { /// 检查OTA固件升级 /// 在BLE连接成功后调用,检查是否需要升级 Future _checkOtaUpgrade() async { - try { - // 防止重复检查 - if (_hasCheckedOta) { - return; - } - - Logger.d(_tag, '开始检查OTA固件升级...'); - - // 检查BLE连接状态 - if (!_isFullyConnected.value) { - Logger.d(_tag, '设备未完全连接,跳过OTA检查'); - return; - } + Logger.d(_tag, '触发OTA升级检查...'); - // 获取当前版本信息 - final currentInfo = await _otaCoreService.getCurrentVersionInfo(); - final currentVersion = currentInfo['currentVersion'] as String; + // 打印当前OTA检查状态(用于调试) + final status = _otaCheckService.getCheckStatus(); + Logger.d(_tag, 'OTA检查状态: $status'); - // 获取最新版本信息 - final latestInfo = await _otaCoreService.getLatestVersionInfo(); - final latestVersion = latestInfo['latestVersion'] as String; + // 使用全局OTA检查服务执行检查 + final success = await _otaCheckService.performOtaCheck(_isFullyConnected.value); - 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; + if (success) { + Logger.d(_tag, 'OTA检查已成功执行'); + } else { + Logger.d(_tag, 'OTA检查被跳过或执行失败'); } } - /// 显示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, - ), - ); + /// 调试方法:获取OTA检查状态 + /// 可以在开发阶段用于调试 + Map getOtaCheckStatus() { + return _otaCheckService.getCheckStatus(); } + + }