cashier_reserve_app/lib/update_version/update_version_view.dart

225 lines
7.2 KiB
Dart

import 'package:cashier_reserve/common/print/print.dart';
import 'package:cashier_reserve/data_model/version/update_version_model.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_app_installer/flutter_app_installer.dart';
import 'package:path_provider/path_provider.dart';
import 'package:percent_indicator/percent_indicator.dart';
class UpdateVersionView extends StatefulWidget {
final UpdateVersionModel versionModel;
const UpdateVersionView({super.key, required this.versionModel});
@override
State<StatefulWidget> createState() {
return _UpdateVersionViewState();
}
}
class _UpdateVersionViewState extends State<UpdateVersionView> {
DateTime? lastPopTime;
double progress = 0;
String progressText = "0%";
bool isDownload = false;
// 用于控制下载任务取消的CancelToken
CancelToken? _cancelToken;
@override
void dispose() {
_cancelToken?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: (widget.versionModel.isUp ?? 0) != 0,
onPopInvokedWithResult: (didPop, result) async {
// 点击返回键的操作
if (lastPopTime == null ||
DateTime.now().difference(lastPopTime!) >
const Duration(seconds: 2)) {
lastPopTime = DateTime.now();
// Utils.toast('再按一次退出', context);
} else {
lastPopTime = DateTime.now();
// 退出app
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
},
child: Scaffold(
backgroundColor: Colors.black.withOpacity(0.2),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: const Color(0x55000000),
child: Center(
child: Container(
padding: const EdgeInsets.fromLTRB(30, 30, 30, 30),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
width: 400,
// height: 400,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"发现新版本",
style:
TextStyle(fontSize: 22, color: Color(0xff333333)),
),
const SizedBox(
height: 20,
),
Text(
widget.versionModel.message ?? "",
style: const TextStyle(
fontSize: 16, color: Color(0xff666666)),
),
const SizedBox(
height: 20,
),
isDownload
? LinearPercentIndicator(
padding: EdgeInsets.zero,
animation: false,
lineHeight: 20.0,
// animationDuration: 2500,
percent: progress,
center: Text(progressText),
// linearStrokeCap: LinearStrokeCap.roundAll,
progressColor: Colors.green,
)
: Container(),
isDownload
? const SizedBox(
height: 20,
)
: Container(),
_buildActionViews(context),
],
),
),
),
),
),
),
),
);
}
Widget _buildActionViews(BuildContext context) {
bool isMustUpdate = widget.versionModel.isUp == 1;
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [
isMustUpdate
? Container()
: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.white),
foregroundColor:
WidgetStateProperty.all(const Color(0xff666666)),
minimumSize: WidgetStateProperty.all(const Size(100, 40)),
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
)),
),
child: const Text("跳过"),
),
isMustUpdate
? Container()
: const SizedBox(
width: 20,
),
ElevatedButton(
onPressed: () {
startDownload();
},
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.blue),
foregroundColor: WidgetStateProperty.all(Colors.white),
minimumSize:
WidgetStateProperty.all(Size(isMustUpdate ? 200 : 100, 40)),
shape: WidgetStateProperty.all(const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20)),
)),
),
child: const Text("立即更新"),
),
]);
}
startDownload() async {
setState(() {
isDownload = true;
});
String fileUrl = widget.versionModel.url ?? "";
if (fileUrl.isEmpty) {
yjPrint("下载地址为空");
return;
}
_cancelToken?.cancel();
setState(() {
progress = 0.0;
progressText = "0.0%";
});
yjPrint("fileUrl: $fileUrl");
Dio dio = Dio();
try {
String savePath = await getPhoneLocalPath();
String appName = "file.apk";
_cancelToken = CancelToken(); // 创建CancelToken对象
await dio.download(
fileUrl, "$savePath$appName", onReceiveProgress: (received, total) {
if (total != -1) {
///当前下载的百分比例
double currentProgress = received / total;
setState(() {
progressText = "${(currentProgress * 100).toStringAsFixed(2)}%";
progress = double.parse(currentProgress.toStringAsFixed(2));
});
yjPrint(progressText);
}
}, cancelToken: _cancelToken);
yjPrint("文件下载成功");
_cancelToken = null;
installApk("$savePath$appName");
} catch (e) {
yjPrint("文件下载失败:$e");
}
}
Future<String> getPhoneLocalPath() async {
final directory = await getExternalStorageDirectory();
return directory?.path ?? '';
}
installApk(String apkPath) async {
final FlutterAppInstaller flutterAppInstaller = FlutterAppInstaller();
flutterAppInstaller.installApk(
filePath: apkPath,
);
}
}