Browse Source

feat(ota): 添加全局OTA检查服务并重构相关逻辑

- 新增OtaCheckService用于全局管理OTA检查状态
- 重构HomeController使用新服务替代原有实现
- 在InitialBinding中注册新服务
weicu
lxm 1 year ago
parent
commit
893ff015f5
  1. 4
      lib/core/bindings/initial_binding.dart
  2. 219
      lib/data/services/ota_check_service.dart
  3. 166
      lib/modules/home/controllers/home_controller.dart

4
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>(() => NoviceGuideService(), fenix: true);
// OTA检查服务
Get.lazyPut<OtaCheckService>(() => OtaCheckService(), fenix: true);
// 杰理蓝牙服务
// // 语言管理器(需要最先初始化)

219
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<OtaCheckService>();
@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<bool> 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<String, dynamic> getCheckStatus() {
return {
'hasCheckedInCurrentSession': _hasCheckedInCurrentSession,
'isCheckingInProgress': _isCheckingInProgress,
'currentRoute': Get.currentRoute,
'isOnHomePage': _isCurrentlyOnHomePage(),
};
}
}

166
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<OtaCheckService>();
_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<void> _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<String, dynamic> getOtaCheckStatus() {
return _otaCheckService.getCheckStatus();
}
}

Loading…
Cancel
Save