177 lines
4.8 KiB
Dart
177 lines
4.8 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart' hide Response;
|
|
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';
|
|
|
|
class DownloadController extends GetxController {
|
|
// 进度条
|
|
var _progressValue = 0.0.obs;
|
|
|
|
double get progressValue => _progressValue.value;
|
|
|
|
set progressValue(double value) {
|
|
_progressValue.value = value;
|
|
}
|
|
|
|
Future<Response> download(String fileUrl, String fullPath) async {
|
|
progressValue = 0;
|
|
return await HttpUtil().dio.download(
|
|
fileUrl,
|
|
fullPath,
|
|
options: Options(
|
|
receiveTimeout: Duration(minutes: 5),
|
|
),
|
|
onReceiveProgress: (count, total) {
|
|
final value = count / total;
|
|
if (progressValue != value) {
|
|
if (progressValue < 1.0) {
|
|
progressValue = count / total;
|
|
} else {
|
|
progressValue = 0.0;
|
|
}
|
|
}
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
/// App 更新
|
|
class AppUpdateUtil {
|
|
static AppUpdateUtil _instance = AppUpdateUtil._internal();
|
|
|
|
factory AppUpdateUtil() => _instance;
|
|
|
|
AppUpdateUtil._internal();
|
|
|
|
AppUpdateResponse? _appUpdateInfo;
|
|
|
|
/// 获取更新信息
|
|
Future run() async {
|
|
// 提交 设备类型、发行渠道、架构、机型
|
|
AppUpdateRequest appUpdateRequest = AppUpdateRequest(
|
|
device: Platform.isIOS ? "ios" : "android",
|
|
channel: ConfigService.channel,
|
|
architecture: ConfigService.isIOS
|
|
? ConfigService.iosDeviceInfo!.utsname.machine
|
|
: ConfigService.androidDeviceInfo!.device,
|
|
model: ConfigService.isIOS
|
|
? ConfigService.iosDeviceInfo!.name
|
|
: ConfigService.androidDeviceInfo!.brand,
|
|
);
|
|
|
|
_appUpdateInfo = await AppRepository().update(appUpdateRequest);
|
|
|
|
_runAppUpdate();
|
|
}
|
|
|
|
/// 检查是否有新版
|
|
Future<void> _runAppUpdate() async {
|
|
// 比较版本
|
|
final isNewVersion =
|
|
_appUpdateInfo!.latestVersion!.compareTo(ConfigService.to.version) > 0;
|
|
|
|
// 发现新版本
|
|
if (isNewVersion) {
|
|
_appUpdateConformDialog(() {
|
|
Get.back(); // 手动关闭对话框
|
|
if (ConfigService.isIOS) {
|
|
// 前往AppStore
|
|
InstallPlugin.gotoAppStore(_appUpdateInfo!.shopUrl!);
|
|
} else {
|
|
// 下载APK
|
|
toastInfo(msg: "开始下载升级包");
|
|
_downloadAPKAndSetup(
|
|
_appUpdateInfo!.fileUrl!, _appUpdateInfo!.latestVersion!);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/// 下载文件 & 安装
|
|
Future<void> _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) {
|
|
final DownloadController downloadController = Get.put(
|
|
DownloadController());
|
|
Get.dialog(
|
|
AlertDialog(
|
|
title: Text('文件下载中'),
|
|
content: Obx(() {
|
|
final percentage = downloadController.progressValue * 100;
|
|
|
|
if (percentage == 100) {
|
|
Get.back();
|
|
}
|
|
|
|
return Row(
|
|
children: [
|
|
Text('正在下载'),
|
|
Expanded(child: LinearProgressIndicator(
|
|
value: downloadController.progressValue)),
|
|
Text(
|
|
"${percentage.toStringAsFixed(0)}%"),
|
|
],
|
|
);
|
|
}),
|
|
),
|
|
barrierDismissible: false,
|
|
);
|
|
await downloadController.download(fileUrl, fullPath);
|
|
|
|
// 释放
|
|
downloadController.dispose();
|
|
}
|
|
// 安装
|
|
await InstallPlugin.installApk(fullPath);
|
|
}
|
|
|
|
/// 升级确认对话框
|
|
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('同意'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|