diff --git a/lib/data/services/config.dart b/lib/data/services/config.dart index e212c8d..4fc8adf 100644 --- a/lib/data/services/config.dart +++ b/lib/data/services/config.dart @@ -1,38 +1,35 @@ import 'dart:io'; +import 'package:device_info/device_info.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:news_getx/config/storage.dart'; import 'package:news_getx/data/services/storage.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:device_info/device_info.dart'; class ConfigService extends GetxService { + /// 静态变量 static ConfigService get to => Get.find(); - bool isFirstOpen = false; - RxBool isGrayFilter = false.obs; - - PackageInfo? _platform; - - /// 发布渠道 + // 发布渠道 static String channel = "xxx"; - /// 是否 ios + // 是否 ios static bool isIOS = Platform.isIOS; - /// android 设备信息 + // android 设备信息 static AndroidDeviceInfo? androidDeviceInfo; - /// ios 设备信息 + // ios 设备信息 static IosDeviceInfo? iosDeviceInfo; + /// 响应式成员变量 + RxBool isGrayFilter = false.obs; - String get version => _platform?.version ?? "-"; + /// 成员变量 + bool isFirstOpen = false; + PackageInfo? _platform; - bool get isRelease => bool.fromEnvironment("dart.vm.product"); - - // Locale locale = Locale("en", "US"); Locale locale = Locale("zh", "CN"); List languages = [ @@ -40,6 +37,11 @@ class ConfigService extends GetxService { Locale('zh', 'CN'), ]; + /// Getter + String get version => _platform?.version ?? "-"; + + bool get isRelease => bool.fromEnvironment("dart.vm.product"); + @override void onInit() async { super.onInit(); @@ -62,6 +64,7 @@ class ConfigService extends GetxService { } Future getPlatform() async { + // 获取包信息 _platform = await PackageInfo.fromPlatform(); } @@ -70,6 +73,7 @@ class ConfigService extends GetxService { return StorageService.to.setBool(StorageDeviceFirstOpenKey, false); } + // 初始化语言环境 暂未使用 void onInitLocale() { String langCode = StorageService.to.getString(StorageLanguageCode); if (langCode.isEmpty) return; @@ -81,6 +85,7 @@ class ConfigService extends GetxService { locale = languages[index]; } + // 改变语言环境 void onLocaleUpdate(Locale value) { locale = value; // 更新app的语言 diff --git a/lib/modules/application/application_controller.dart b/lib/modules/application/application_controller.dart index 83f4303..d548b0c 100644 --- a/lib/modules/application/application_controller.dart +++ b/lib/modules/application/application_controller.dart @@ -4,8 +4,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; +import 'package:news_getx/data/provider/app.dart'; +import 'package:news_getx/data/services/config.dart'; import 'package:news_getx/theme/app_colors.dart'; import 'package:news_getx/utils/iconfont.dart'; +import 'package:news_getx/utils/update.dart'; +import 'package:permission_handler/permission_handler.dart'; import 'package:uni_links/uni_links.dart'; class ApplicationController extends GetxController { @@ -150,6 +154,24 @@ class ApplicationController extends GetxController { ]; pageController = PageController(initialPage: page); + + // 系统更新检查 + if (ConfigService.to.isRelease) { + doAppUpdate(); + } + } + + Future doAppUpdate() async { + // 延迟三秒 用户体验好些 + await Future.delayed(Duration(seconds: 3), () async { + if (ConfigService.isIOS == false && + await Permission.storage.isGranted == false) { + await [Permission.storage].request(); + } + if (await Permission.storage.isGranted) { + AppUpdateUtil().run(); + } + }); } @override diff --git a/lib/modules/bookmarks/bookmarks_page.dart b/lib/modules/bookmarks/bookmarks_page.dart index 403eafe..50f5981 100644 --- a/lib/modules/bookmarks/bookmarks_page.dart +++ b/lib/modules/bookmarks/bookmarks_page.dart @@ -15,4 +15,3 @@ class BookmarksPage extends GetView { ); } } - diff --git a/lib/utils/update.dart b/lib/utils/update.dart index 3179c6d..1fa3c03 100644 --- a/lib/utils/update.dart +++ b/lib/utils/update.dart @@ -1,72 +1,15 @@ import 'dart:io'; -import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:install_plugin/install_plugin.dart'; import 'package:news_getx/data/model/app.dart'; import 'package:news_getx/data/repository/app_repository.dart'; import 'package:news_getx/data/services/config.dart'; +import 'package:news_getx/modules/widgets/toast.dart'; +import 'package:news_getx/utils/http.dart'; import 'package:path_provider/path_provider.dart'; -// todo 如何用完一次就消失 -class DownloadController extends GetxController { - // 进度条 - var _progressValue = 0.0.obs; - - double get progressValue => _progressValue.value; - - set progressValue(double value) { - _progressValue.value = value; - } - - /// 下载文件 & 安装 - Future _downloadAPKAndSetup(fileUrl) async { - _progressValue.value = 0.0; - - // 下载 - Directory? externalDir = await getExternalStorageDirectory(); - - if (externalDir == null) { - return; - } - // 存储路径 - String fullPath = "${externalDir.path}/release.apk"; - - // Dio dio = Dio(BaseOptions( - // responseType: ResponseType.bytes, - // followRedirects: false, - // validateStatus: (status) { - // return status! < 500; - // } - // )); - // - // // 获取APP文件 - // Response response = await dio.get(fileUrl); - // - // // 文件写入 - // File file = File(fullPath); - // var raf = file.openSync(mode: FileMode.write); - // raf.writeByteSync(response.data); - // await raf.close(); - - await Dio().download(fileUrl, fullPath, onReceiveProgress: (count, total) { - final value = count / total; - if (_progressValue.value != value) { - if (_progressValue.value < 1.0) { - _progressValue.value = count / total; - } else { - _progressValue.value = 0.0; - } - print("${(_progressValue * 100).toStringAsFixed(0)}%"); - } - }); - - // 安装 - await InstallPlugin.installApk(fullPath); - } -} - /// App 更新 class AppUpdateUtil { static AppUpdateUtil _instance = AppUpdateUtil._internal(); @@ -97,30 +40,77 @@ class AppUpdateUtil { } /// 检查是否有新版 - Future _runAppUpdate() async { + Future _runAppUpdate() async { // 比较版本 final isNewVersion = _appUpdateInfo!.latestVersion!.compareTo(ConfigService.to.version) > 0; // 发现新版本 if (isNewVersion) { - // todo 确认弹窗 确认完成下载并显示进度条 - Get.defaultDialog( - title: "发现新版本 ${_appUpdateInfo!.latestVersion}", - content: GetBuilder( - init: DownloadController(), - builder: (controller) { - return LinearProgressIndicator(value: controller.progressValue); - }, - ), - ); - - // _appUpdateConformDialog( - // - // ); + _appUpdateConformDialog(() { + Get.back(); // 手动关闭对话框 + if (ConfigService.isIOS) { + // 前往AppStore + InstallPlugin.gotoAppStore(_appUpdateInfo!.shopUrl!); + } else { + // 下载APK + toastInfo(msg: "开始下载升级包"); + _downloadAPKAndSetup( + _appUpdateInfo!.fileUrl!, _appUpdateInfo!.latestVersion!); + } + }); } } + /// 下载文件 & 安装 + Future _downloadAPKAndSetup(String fileUrl, String version) async { + // 下载 + Directory? externalDir = await getExternalStorageDirectory(); + + if (externalDir == null) { + toastInfo(msg: "获取文件夹信息失败"); + return; + } + + String filename = "release-{$version}.apk"; + // 存储路径 + String fullPath = "${externalDir.path}/$filename"; + bool isFileFound = false; + + final files = externalDir.listSync(); + for (FileSystemEntity file in files) { + if (file is File && file.path.endsWith(filename)) { + isFileFound = true; + break; + } + } + + if (!isFileFound) { + await HttpUtil().dio.download(fileUrl, fullPath); + } + // 安装 + await InstallPlugin.installApk(fullPath); + } + /// 升级确认对话框 - void _appUpdateConformDialog(VoidCallback onPressed) {} + void _appUpdateConformDialog(VoidCallback onPressed) { + Get.dialog( + AlertDialog( + title: Text('发现新版本 ${_appUpdateInfo!.latestVersion}'), + content: Text(_appUpdateInfo!.latestDescription ?? ''), + actions: [ + TextButton( + child: Text('取消'), + onPressed: () { + Get.back(); // 手动关闭对话框 + }, + ), + ElevatedButton( + onPressed: onPressed, + child: Text('同意'), + ), + ], + ), + ); + } }