import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:path/path.dart'; import 'dart:async'; import '../../../data/services/network/api.dart'; import '../model/ota_upgrade_model.dart'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:path_provider/path_provider.dart'; import 'package:jl_ota/jl_ota.dart'; import '../../../data/services/ble_manager.dart'; class OtaUpgradeController extends GetxController { final RxString errorMessage = ''.obs; final RxBool isFetchingDeviceInfo = false.obs; final Dio _dio = Dio(); final RxString latestVersion = ''.obs; final RxString currentVersion = ''.obs; String updatepackageaddress = ''; final RxDouble downloadProgress = 0.0.obs; final RxBool isUpdating = false.obs; final isUpdateAvailable = true.obs; final RxDouble progress = 0.0.obs; // 蓝牙服务 final _bleManager = Get.find(); @override void onInit() { super.onInit(); _getCurrentVersion(); } // 添加重试方法 void retryConnection() { errorMessage.value = ''; _getCurrentVersion(); } // 添加更新方法 Future startUpdate() async { try { isUpdating.value = true; checkUpdate(); // 实现更新逻辑... } catch (e) { errorMessage.value = e.toString(); Get.snackbar('更新失败', e.toString()); } finally { isUpdating.value = false; } } Future _getCurrentVersion() async { JlOta().getPlatformVersion(); //try { // // 添加获取设备信息的重试机制 // DeviceInfo? deviceInfo = _bleManager.deviceInfo.value; // // 第一次检查设备信息 // if (deviceInfo == null) { // // 显示加载提示 // isFetchingDeviceInfo.value = true; // // 尝试重新获取设备信息 // await _bleManager.fetchDeviceInfo(); // // 等待后再次获取设备信息 // deviceInfo = _bleManager.deviceInfo.value; // isFetchingDeviceInfo.value = false; // // 仍然为空则抛出异常 // if (deviceInfo == null) { // throw const FormatException('无法获取设备信息,请检查设备连接'); // } // } // // 检查固件信息有效性 // if (deviceInfo.firmwareVersion.isEmpty // // || // // deviceInfo.firmwareProductId.isEmpty // ) { // throw const FormatException('设备固件信息不完整'); // } // // 正常流程 // currentVersion.value = "0"; //deviceInfo.firmwareVersion; // // API请求 // final response = await Api.getequipmentinfo({ // "id": "s3", // }); // // 处理API响应 // if (response['info'] == null) { // throw const FormatException('API 响应格式错误'); // } // final resp = OtaConfigResp.fromJson(response); // latestVersion.value = resp.systemversion!; // updatepackageaddress = resp.updatepackageaddress!; // // 版本检查 // isUpdateAvailable.value = _isNewVersionAvailable(resp.systemversion!); // } catch (e) { // // 统一错误处理 // errorMessage.value = e.toString(); // Get.snackbar('错误', e.toString(), // snackPosition: SnackPosition.BOTTOM, // backgroundColor: Colors.red, // colorText: Colors.white); // // 重要:重新抛出异常以便上层处理(可选) // } finally { // isFetchingDeviceInfo.value = false; // } } // 版本比较方法优化 bool _isNewVersionAvailable(String latest) { try { List currentParts = currentVersion.value .split('.') .map((e) => int.parse(e.trim())) .toList(); List latestParts = latest.split('.').map((e) => int.parse(e.trim())).toList(); for (int i = 0; i < latestParts.length; i++) { int current = (i < currentParts.length) ? currentParts[i] : 0; if (latestParts[i] > current) return true; if (latestParts[i] < current) return false; } return false; } catch (e) { print('版本比较错误: $e'); return false; } } // 版本更新 Future checkUpdate() async { try { if (latestVersion.value != "") _showUpdateDialog(latestVersion.value); else { Get.snackbar('错误', '获取最新版本信息失败'); } } catch (e) { Get.snackbar('错误', '获取版本信息失败'); } } // 显示更新对话框 void _showUpdateDialog(String latest) { Get.dialog( AlertDialog( title: Text('发现新版本 $latest'), content: Text('是否立即更新?'), actions: [ TextButton( onPressed: () => Get.back(), child: Text('取消'), ), TextButton( onPressed: () { Get.back(); startDownload(); }, child: Text('更新'), ), ], ), ); } // 修改后的startDownload方法 Future startDownload() async { isUpdating.value = true; int lastIndex = updatepackageaddress.lastIndexOf('/'); String fileName = updatepackageaddress.substring(lastIndex + 1); String directoryName = "ota_upgrades"; final dio = Dio(BaseOptions( connectTimeout: const Duration(seconds: 5), receiveTimeout: Duration.zero, sendTimeout: const Duration(seconds: 5), headers: {'Accept-Encoding': 'gzip'}, )); Get.snackbar('升级命令已发送', '开始下载...'); try { final Directory? downloadsDir = await getDownloadsDirectory(); if (downloadsDir == null) { throw FileSystemException('无法访问下载目录'); } final targetDir = Directory('${downloadsDir.path}/$directoryName'); if (!await targetDir.exists()) { await targetDir.create(recursive: true); } final savePath = '${targetDir.path}/$fileName'; // 新增:检查同名文件逻辑 bool existingSameFile = false; try { var files = await targetDir.list().toList(); for (var entity in files) { if (await FileSystemEntity.isFile(entity.path)) { String name = basename(entity.path); // 使用path包中的basename if (name == fileName) { existingSameFile = true; break; } } } } catch (e) { Get.snackbar('错误', '检查本地文件失败: $e'); isUpdating.value = false; return; } if (existingSameFile) { Get.snackbar('文件已存在', '跳过下载,直接更新'); isUpdating.value = false; _installApp(savePath); return; } // 新增:删除其他文件逻辑 try { var files = await targetDir.list().toList(); for (var entity in files) { if (await FileSystemEntity.isFile(entity.path)) { await entity.delete(); } } } catch (e) { Get.snackbar('错误', '删除旧文件失败: $e'); isUpdating.value = false; return; } print('文件保存路径: $savePath'); final options = Options( receiveTimeout: Duration.zero, followRedirects: true, maxRedirects: 5, ); DateTime lastUpdate = DateTime.now(); await dio.download( updatepackageaddress, savePath, options: options, onReceiveProgress: (received, total) { final now = DateTime.now(); if (now.difference(lastUpdate).inMilliseconds > 1000) { lastUpdate = now; String progressMsg = total != -1 ? '${(received / total * 100).toStringAsFixed(1)}%' : '已下载:${(received / 1024 / 1024).toStringAsFixed(1)}MB'; Get.snackbar( '升级进度', progressMsg, duration: const Duration(seconds: 1), ); } }, ); File file = File(savePath); if (await file.exists()) { Get.snackbar('下载完成', '文件已保存至: $savePath'); } else { Get.snackbar('错误', '文件未找到,请检查写入权限'); } isUpdating.value = false; _installApp(savePath); } on DioException catch (e) { Get.snackbar('下载失败', '错误: ${e.message}'); isUpdating.value = false; } on FileSystemException catch (e) { Get.snackbar('存储失败', '无法写入文件: ${e.message}'); isUpdating.value = false; } catch (e) { Get.snackbar('未知错误', e.toString()); isUpdating.value = false; } } // 开始升级 void _installApp(String path) async { // JlOtaPlugin() // final File file = File(path); // if (await file.exists()) { // // OpenResult result = await OpenFile.open(path); // // if (result.type != ResultType.done) { // // Get.snackbar('错误', '安装失败: ${result.message}'); // // } // } } }