/* * @Descripttion: 下载APK * @version: DownloadApk * @Author: wy * @Date: 2020-07-30 15:54:40 * @LastEditors: wangyang 1147192855@qq.com * @LastEditTime: 2022-08-02 15:12:21 */ import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:install_plugin/install_plugin.dart'; import 'package:marking_app/provider/upgrade_provider.dart'; import 'package:marking_app/utils/app_upgrade/model/UpdateAppEvent.dart'; import 'package:marking_app/utils/index.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:path_provider/path_provider.dart'; import 'package:app_installer/app_installer.dart'; import 'package:url_launcher/url_launcher.dart'; import 'UpgradePermission.dart'; class DownloadApk { /// 下载安卓更新包 static Future _downloadAndroid(context, UpdateAppEvent event, WidgetRef ref) async { /// 创建存储文件 Directory? storageDir = await getExternalStorageDirectory(); final storagePath = storageDir?.path ?? '/'; String version = event.version.replaceAll(".", "-"); File file = new File('$storagePath/${event.appName}v$version.apk'); if (await file.exists()) await file.delete(); if (!file.existsSync()) file.createSync(); try { /// 发起下载请求 Response response = await Dio().get( event.link, onReceiveProgress: (num received, num total) { showDownloadProgress(context, received, total, ref); }, options: Options( responseType: ResponseType.bytes, followRedirects: false, ), ); file.writeAsBytesSync(response.data); return file; } catch (e) { print(e); // toPrint(val: e); } } // 安装apk static Future installApk(context, UpdateAppEvent event, WidgetRef ref) async { File? _apkFile = await _downloadAndroid(context, event, ref); if (_apkFile == null) return false; String _apkFilePath = _apkFile.path; if (_apkFilePath.isEmpty) { debugPrint('make sure the apk file is set'); return false; } try { await showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: const Text("未知应用安装权限提示"), content: const Text("更新时若出现需要同意安装未知应用权限时,请同意"), actions: [ MaterialButton( color: Theme.of(context).primaryColor, child: const Text("我已知晓", style: TextStyle(color: Colors.white)), onPressed: () => Navigator.of(context).pop(), ), ], ); }, ); await AppInstaller.installApk(_apkFilePath); // 安装APK // 如果2秒还没有进入安装引导页面 一律视为更新失败,弹出其他方式更新 await setTimeOut(5000, () async { try { // 其他方式下载 // await SystemNavigator.pop(); // 退出APP var options = ['应用市场更新APP', '浏览器下载并安装APP']; var uri = Uri.parse('market://details?id=com.example.marking_app'); // 应用市场URI if (!await canLaunchUrl(uri)) options.removeAt(0); // 如果不能打开应用市场 就屏蔽掉 这个安装方式 String? option = await UpgradePermission.showCustomModalBottomSheet(context, options); if (option == '应用市场更新APP') await launchUrl(uri); if (option == '浏览器下载并安装APP') await launchUrl(Uri.parse(event.link)); } catch (e) {} }); print('安装执行完成了..............0.0'); } catch (e) { print('安装进入报错....'); print(e); } return false; } /// 展示下载进度 static void showDownloadProgress(context, num received, num total, WidgetRef ref) { if (total != -1) { double progress = double.parse((received / total).toStringAsFixed(2)); // debugPrint('下载进度$progress'); ref.read(upgradeProvider.notifier).setVal(progress); } } } class RestartWidget extends StatefulWidget { final Widget child; RestartWidget({required this.child}); static restartApp(BuildContext context) { final _RestartWidgetState? state = context.findAncestorStateOfType<_RestartWidgetState>(); state?.restartApp(); } @override _RestartWidgetState createState() => _RestartWidgetState(); } class _RestartWidgetState extends State { Key key = UniqueKey(); void restartApp() { setState(() { key = UniqueKey(); }); } @override Widget build(BuildContext context) { return KeyedSubtree( key: key, child: widget.child, ); } }