import 'dart:io'; import 'package:ctjt_flutter/common/states.dart'; import 'package:ctjt_flutter/common/styles.dart'; import 'package:ctjt_flutter/common/utils.dart'; import 'package:ctjt_flutter/service/app_service.dart'; import 'package:ctjt_flutter/widget/button.dart'; import 'package:ctjt_flutter/widget/contact.dart'; import 'package:ctjt_flutter/widget/title.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:r_upgrade/r_upgrade.dart'; // 关于页(APP更新页) class AboutPage extends StatefulWidget { AboutPage({Key? key}) : super(key: key); @override _AboutPageState createState() => _AboutPageState(); } class _AboutPageState extends State { final _formKey = GlobalKey(); late AppService _appService; bool isLatest = false; static const String LoadingTip = '正在获取...'; TextEditingController _latestVersionController = TextEditingController(text: LoadingTip); String _downloadUrl = ""; String _versionDescription = ""; @override void initState() { super.initState(); _appService = AppService.getInstance(this.context); initVersion(); } Future initVersion() async { // 在common中初始化时,已获取当前APP版本并缓存,本地APP版本相对稳定,此处不再获取 // 从服务器获取手机APP新版本信息 var localVersion = Provider.of(context, listen: false).appVersion; var resp = await _appService.fetchVersionInfo(localVersion); if (null == resp || resp.status != 1 || (resp.targetVersion!.isNotEmpty && resp.targetVersion!.trim() != localVersion)) { _latestVersionController.text = localVersion; isLatest = true; return; } setState(() { _downloadUrl = resp.url!; _versionDescription = resp.instructions!; var lv = Version(localVersion); var rv = Version(resp.lastVersion!); if (rv.moreThan(lv)) { _latestVersionController.text = '${lv.origin} -> ${rv.origin}'; isLatest = false; } else { _latestVersionController.text = lv.origin; isLatest = true; } }); } // 下载进度对话框 void _showDownloadDialog() { showDialog( // 下载对话框 context: context, barrierDismissible: false, // 点击遮罩不关闭 builder: (context) { return SimpleDialog( title: Text('更新', style: TextStyle(color: Styles.primaryColor)), children: [ Offstage( // 更新说明 offstage: _versionDescription.trim() != "", child: Container( height: 600.h, child: SingleChildScrollView( child: Text(_versionDescription.trim()), )), ), Container( // 进度条 height: 200.h, alignment: Alignment.centerLeft, padding: EdgeInsets.only( left: 60.w, right: 60.w), child: Column( children: [ Container( // 条状进度条 margin: EdgeInsets.symmetric( horizontal: 50.w, vertical: 50.h), height: 25.h, child: LinearProgressIndicator( backgroundColor: Styles.primaryColor, value: Provider.of(context) .process, //设置比例 valueColor: AlwaysStoppedAnimation(Colors.black), // Navigator.of(mContext).pop(); // 下载完成关闭对话框 ), ), Text('正在为您更新,请耐心等待。'), ], ), ), ]); }, ); } @override Widget build(BuildContext context) { return Form( key: _formKey, child: Scaffold( backgroundColor: Colors.white, appBar: PageHead(), body: Container( padding: Styles.primaryPadding, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题 PageTitle(text: "关于"), Padding( padding: EdgeInsets.only( top: 75.h, bottom: 75.h), child: Text('最新应用软件版本:', style: Styles.configDescStyle), ), TextFormField( controller: _latestVersionController, readOnly: true, enabled: false, decoration: InputDecoration( suffixIcon: isLatest ? Icon(Icons.done, color: Styles.primaryColor, size: Styles.iconSize) : Icon(Icons.rotate_right, color: Styles.primaryColor, size: Styles.iconSize), ), ), Padding( padding: EdgeInsets.only(top: 25.h), child: Text(isLatest ? '您的APP是最新的' : '有新的APP版本,点击按钮立即更新', style: Styles.configDescStyle), ), // 更新按钮 Offstage( offstage: isLatest, child: BigSButton( text: '更新', onPressed: () async { if (Platform.isIOS) { _launchToAppStore(); } else if (Platform.isAndroid) { var hasPermission = await Utils.checkPermission(Permission.storage); if (hasPermission) { _installApk( _downloadUrl, _latestVersionController.text); _showDownloadDialog(); } else { Fluttertoast.showToast( msg: "安装更新需要存储权限,该权限未打开", toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 3); } } else { print('A platform witch unsupported.' + Platform.operatingSystem + ' ' + Platform.operatingSystemVersion); } }, ), ), Offstage( offstage: Provider.of(context).userToken.isEmpty, child: BigSButton( text: '退出登录', onPressed: () { States.reset(context); }, ), ), TButton( child: Text("用户协议和隐私政策", style: TextStyle(color: Styles.linkColor)), onPressed: () { Contact.showUserContactDialog(context); }, ), ], ), ), ), ); } /// 跳转到App Store指定页,用于IOS Future _launchToAppStore() async { // 参数为APP Store中的应用ID,对应APP Store页面 https://apps.apple.com/cn/app/XXXX/id1234 RUpgrade.upgradeFromAppStore('id1234') .then((result) { print('install apk $result'); }).catchError((error) { print('install apk error: $error'); }); } /// 下载并安装APK,用于Android Future _installApk(String url, String version) async { Directory? storageDir = await getExternalStorageDirectory(); if (null == storageDir) { print('can not get storage dir'); _showDownloadErrorDialog(); return; } String storagePath = storageDir.path; String fileName = '$storagePath/lyiew_v$version.apk'; RUpgrade.stream.listen((DownloadInfo info) { // 下载进度监听,通过状态通知更新界面进度条 Provider.of(context, listen: false).process = info.percent!; }); RUpgrade.upgrade(url, fileName: fileName, isAutoRequestInstall: true) // 下载并安装 .then((result) { print('install apk $result'); }).catchError((error) { print('install apk error: $error'); }); } // 下载失败提示对话框 void _showDownloadErrorDialog() { showDialog( context: context, builder: (context) { return SimpleDialog( title: Text('提示', style: TextStyle(color: Styles.primaryColor)), children: [ Container( height: 200.h, alignment: Alignment.centerLeft, padding: EdgeInsets.only( left: 60.h, right: 60.h), child: Text('下载失败。'), ), Divider(), TButton( child: Text("确定", style: TextStyle(fontWeight: FontWeight.w700)), onPressed: () { // 关闭对话框 Navigator.of(context).pop(); }) ]); }); } }