import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'dart:async'; import 'dart:convert'; import 'package:get_storage/get_storage.dart'; import '../../../data/services/network/api.dart'; import '../ota.dart'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:path_provider/path_provider.dart'; import 'package:json_annotation/json_annotation.dart'; class OtaUpgradeController extends GetxController { 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; @override void onInit() { super.onInit(); _getCurrentVersion(); } // 获取当前版本信息 Future _getCurrentVersion() async { //发送ble获取固件版本 var firmwareVersion = "1.1.0"; currentVersion.value = firmwareVersion; //发送ble获取产品id var id = "a2"; //发送api请求 final response = await Api.getequipmentinfo({ "id": id, }); if (response['info'] != '') { print('getLoginToken:进来了'); // 根据API设计调整 final resp = OtaConfigResp.fromJson(response); print('成功解析: ${resp.id}, ${resp.factory}'); latestVersion.value = resp.systemversion!; updatepackageaddress = resp.updatepackageaddress!; if (_isNewVersionAvailable(resp.systemversion!)) { //需要升级 print('需要更新'); isUpdateAvailable.value = false; } else { isUpdateAvailable.value = true; //已经是最新版本更新ui,按钮隐藏 } } else { throw const FormatException('API 响应缺少 "info" 字段'); } } // 版本比较方法优化 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('更新'), ), ], ), ); } // 开始下载 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('无法访问下载目录'); } // 创建子目录:Download/APP final targetDir = Directory('${downloadsDir.path}/$directoryName'); if (!await targetDir.exists()) { await targetDir.create(recursive: true); } final savePath = '${targetDir.path}/$fileName'; 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}'); } on FileSystemException catch (e) { Get.snackbar('存储失败', '无法写入文件: ${e.message}'); } catch (e) { Get.snackbar('未知错误', e.toString()); } } // 开始升级 void _installApp(String path) async { // final File file = File(path); // if (await file.exists()) { // // OpenResult result = await OpenFile.open(path); // // if (result.type != ResultType.done) { // // Get.snackbar('错误', '安装失败: ${result.message}'); // // } // } } }