|
|
import 'dart:async';
|
|
|
import 'dart:io';
|
|
|
|
|
|
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
|
|
|
///1、导入相关包
|
|
|
import 'dart:isolate';
|
|
|
import 'dart:ui';
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_downloader/flutter_downloader.dart';
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
import 'package:hyzp_ybqx511528_xingwen/components/dioFun.dart';
|
|
|
import 'package:open_file/open_file.dart';
|
|
|
import 'package:package_info/package_info.dart';
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
import 'package:progress_dialog/progress_dialog.dart';
|
|
|
|
|
|
import '../../../components/commonFun.dart';
|
|
|
import '../../../widget/JdButton.dart';
|
|
|
|
|
|
///版本更新頁面
|
|
|
class MyUpdated extends StatefulWidget {
|
|
|
MyUpdated({Key key, this.ver, this.date, this.theContext}) : super(key: key);
|
|
|
String ver = '1.0.0';
|
|
|
String date = '';
|
|
|
BuildContext theContext;
|
|
|
|
|
|
_MyUpdatedState createState() => _MyUpdatedState();
|
|
|
}
|
|
|
|
|
|
class _MyUpdatedState extends State<MyUpdated> {
|
|
|
//2、声明变量
|
|
|
int _stampAppCompile = -1;
|
|
|
String _dateNewver = '';
|
|
|
Map _mapVer = {};
|
|
|
String serviceVersionCode = '';
|
|
|
String appId = '';
|
|
|
ProgressDialog pr;
|
|
|
String apkName = 'app-release.apk';
|
|
|
String appPath = '';
|
|
|
ReceivePort _port = ReceivePort();
|
|
|
|
|
|
void initState() {
|
|
|
// 0、初始化FlutterDownLoader。版本更新初始化,放在这里会报错,初始化失败
|
|
|
// WidgetsFlutterBinding.ensureInitialized();
|
|
|
if (!bFlutterDownloader_initialize) {
|
|
|
FlutterDownloader.initialize(debug: true).then((value) {
|
|
|
//3、在initState中初始化
|
|
|
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
|
|
|
_port.listen(_updateDownLoadInfo);
|
|
|
FlutterDownloader.registerCallback(_downLoadCallback);
|
|
|
getNewverUrl().then((value) {
|
|
|
_mapVer = value;
|
|
|
print('_mapVer = ${_mapVer}');
|
|
|
});
|
|
|
bFlutterDownloader_initialize = true;
|
|
|
});
|
|
|
} else {
|
|
|
//3、在initState中初始化
|
|
|
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
|
|
|
_port.listen(_updateDownLoadInfo);
|
|
|
FlutterDownloader.registerCallback(_downLoadCallback);
|
|
|
getNewverUrl().then((value) {
|
|
|
_mapVer = value;
|
|
|
print('_mapVer = ${_mapVer}');
|
|
|
//I/flutter (12498): _mapVer = {id: 1, ver: 1.0.0, miaos: 版本说明,
|
|
|
// downurl: http://www.sctastech.com/download/hyzp_20210425.apk, updatetime: 1620632231}
|
|
|
|
|
|
print('oldVer = ${widget.ver}');
|
|
|
_mapVer['ver'] = '1.3.1';
|
|
|
print('newVer = ${_mapVer['ver']}');
|
|
|
// I/flutter ( 1872): oldVer = 1.3.0
|
|
|
// I/flutter ( 1872): newVer = 1.3.1
|
|
|
|
|
|
///从字符串时间获取秒时间戳:int getStampFromString(String strTime)
|
|
|
// _stampAppCompile = getStampFromString(widget.date.replaceAll('.', '-'));
|
|
|
// //timeStamp可以是int类型或String类型的时间戳(秒):String getFtpdir_YYYYMMDD(var timeStamp)
|
|
|
// _dateNewver = getFtpdir_YYYYMMDD(_mapVer['updatetime'], sep: '.');
|
|
|
// print('_stampAppCompile = $_stampAppCompile');
|
|
|
// print('_mapVer[\'updatetime\'] = ${_mapVer['updatetime']}');
|
|
|
// print('widget.date = ${widget.date}');
|
|
|
// print('_dateNewver = $_dateNewver');
|
|
|
// I/flutter (30820): _stampAppCompile = 1620403200
|
|
|
// I/flutter (30820): _mapVer['updatetime'] = 1620632231
|
|
|
// I/flutter (30820): widget.date = 2021.05.08
|
|
|
// I/flutter (30820): _dateNewver = 2021.05.10
|
|
|
});
|
|
|
}
|
|
|
|
|
|
super.initState();
|
|
|
}
|
|
|
|
|
|
//4、判断,自动更新
|
|
|
|
|
|
// 版本比较
|
|
|
Future verCompare({String newVer, String oldVer}) async {
|
|
|
List listNewVer = await tran2int(newVer.split('.'));
|
|
|
List listOldVer = await tran2int(oldVer.split('.'));
|
|
|
|
|
|
int len = listNewVer.length;
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
if (listNewVer[i] > listOldVer[i]) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
Future tran2int(List _list) async {
|
|
|
List listRet = [];
|
|
|
int len = _list.length;
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
listRet.add(int.parse(_list[i].trim()));
|
|
|
}
|
|
|
return listRet;
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
Future afterFirstLayout(BuildContext context) async {
|
|
|
// 如果是android,则执行热更新
|
|
|
if (Platform.isAndroid) {
|
|
|
verCompare(newVer: _mapVer['ver'], oldVer: widget.ver).then((value) {
|
|
|
if (value) {
|
|
|
print('value = $value');
|
|
|
//_getNewVersionAPP(context);
|
|
|
serviceVersionCode = _mapVer['ver'];
|
|
|
//appId = res.data['id'];
|
|
|
//_checkVersionCode();
|
|
|
_showNewVersionAppDialog();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//监听登录页面销毁的事件
|
|
|
dispose() {
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
doLogin() async {
|
|
|
//临时跳转
|
|
|
//Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
|
|
|
afterFirstLayout(context).then((value) {});
|
|
|
//Navigator.pop(context); //返回
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Scaffold(
|
|
|
appBar: PreferredSize(
|
|
|
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)),
|
|
|
// 设置appBar高度
|
|
|
// 设置appBar高度
|
|
|
child: AppBar(
|
|
|
automaticallyImplyLeading: false,
|
|
|
centerTitle: true,
|
|
|
titleSpacing: 0.0,
|
|
|
//设置title的左边距
|
|
|
flexibleSpace: Container(
|
|
|
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
|
|
|
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
|
|
|
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight),
|
|
|
//留出顶部状态栏高度
|
|
|
child: Container(
|
|
|
//height: ScreenUtil().setHeight(173),
|
|
|
decoration: BoxDecoration(
|
|
|
gradient: LinearGradient(
|
|
|
begin: Alignment.centerLeft,
|
|
|
end: Alignment.centerRight,
|
|
|
colors: [
|
|
|
Color.fromRGBO(12, 186, 156, 1),
|
|
|
Color.fromRGBO(39, 127, 235, 1),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
// decoration: BoxDecoration(
|
|
|
// gradient: LinearGradient(colors: [
|
|
|
// Color(0xFF0018EB),
|
|
|
// Color(0xFF01C1D9),
|
|
|
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
|
|
|
// ),
|
|
|
),
|
|
|
),
|
|
|
title: Padding(
|
|
|
padding: EdgeInsets.only(left: 0, right: 0),
|
|
|
child: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
children: [
|
|
|
getIconAndTextButton(
|
|
|
iconColor: Colors.white,
|
|
|
iconData: Icons.chevron_left_outlined,
|
|
|
onPress: () {
|
|
|
Navigator.pop(context);
|
|
|
},
|
|
|
),
|
|
|
Expanded(
|
|
|
child: Text("版本更新",
|
|
|
style: TextStyle(color: Colors.white, fontSize: 20),
|
|
|
textAlign: TextAlign.center,
|
|
|
overflow: TextOverflow.ellipsis),
|
|
|
),
|
|
|
SizedBox(width: 50),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
body: Container(
|
|
|
padding: EdgeInsets.only(top: 20, bottom: 20, left: 5, right: 5),
|
|
|
child: ListView(
|
|
|
children: <Widget>[
|
|
|
Center(
|
|
|
child: Container(
|
|
|
margin: EdgeInsets.only(top: 30),
|
|
|
height: ScreenUtil().setWidth(160),
|
|
|
width: ScreenUtil().setWidth(160),
|
|
|
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
|
|
|
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
|
|
|
// child: Image.network(
|
|
|
// 'https://www.itying.com/images/flutter/list5.jpg',
|
|
|
// fit: BoxFit.cover),
|
|
|
),
|
|
|
),
|
|
|
Center(
|
|
|
child: Column(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: <Widget>[
|
|
|
SizedBox(height: 60),
|
|
|
// Text('宜宾市翠屏黑烟车电子抓拍系统', style: TextStyle(fontSize: 20)),
|
|
|
Text(yibin_QuXian + '黑烟车电子抓拍系统', style: TextStyle(fontSize: 20)),
|
|
|
Text('v${widget.ver}(${widget.date})', style: TextStyle(fontSize: 20)),
|
|
|
SizedBox(height: 60),
|
|
|
//Text('© 宜宾市翠屏生态环境局 版权所有',
|
|
|
Text(copyright_info,
|
|
|
maxLines: 2, style: TextStyle(fontSize: 16), textAlign: TextAlign.center),
|
|
|
// Text('© 宜宾市翠屏生态环境局 四川省踏石科技 版权所有\n服务热线:187-8467-8300',
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
SizedBox(height: 100),
|
|
|
Container(
|
|
|
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
|
|
|
child: JdButton(
|
|
|
height: 126,
|
|
|
text: "确认",
|
|
|
color: Colors.blueAccent,
|
|
|
onTop: doLogin,
|
|
|
),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
|
|
|
//5、自动更新代码
|
|
|
/// 执行版本更新的网络请求
|
|
|
_getNewVersionAPP(context) async {
|
|
|
// HttpUtils.send(
|
|
|
// context,
|
|
|
// 'http://update.rwworks.com:8088/appManager/monitor/app/version/check/flutterTempldate',
|
|
|
// ).then((res) {
|
|
|
// serviceVersionCode = res.data["versionNo"];
|
|
|
// appId = res.data['id'];
|
|
|
// _checkVersionCode();
|
|
|
// });
|
|
|
}
|
|
|
|
|
|
/// 检查当前版本是否为最新,若不是,则更新
|
|
|
void _checkVersionCode() {
|
|
|
PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
|
|
|
var currentVersionCode = packageInfo.version;
|
|
|
if (double.parse(serviceVersionCode.substring(0, 3)) >
|
|
|
double.parse(currentVersionCode.substring(0, 3))) {
|
|
|
_showNewVersionAppDialog();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// 版本更新提示对话框
|
|
|
Future<void> _showNewVersionAppDialog() async {
|
|
|
return showDialog<void>(
|
|
|
context: context,
|
|
|
barrierDismissible: false,
|
|
|
builder: (BuildContext context) {
|
|
|
return AlertDialog(
|
|
|
title: new Row(
|
|
|
children: <Widget>[
|
|
|
new Padding(
|
|
|
padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0),
|
|
|
child: new Text("发现新版本"))
|
|
|
],
|
|
|
),
|
|
|
content: new Text(serviceVersionCode),
|
|
|
actions: <Widget>[
|
|
|
new FlatButton(
|
|
|
child: new Text('下次再说'),
|
|
|
onPressed: () {
|
|
|
Navigator.of(context).pop();
|
|
|
},
|
|
|
),
|
|
|
new FlatButton(
|
|
|
child: new Text('立即更新'),
|
|
|
onPressed: () {
|
|
|
_doUpdate(context);
|
|
|
},
|
|
|
)
|
|
|
],
|
|
|
);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// 执行更新操作
|
|
|
_doUpdate(BuildContext context) async {
|
|
|
Navigator.pop(context);
|
|
|
_executeDownload(context);
|
|
|
}
|
|
|
|
|
|
/// 下载最新apk包
|
|
|
Future<void> _executeDownload(BuildContext context) async {
|
|
|
pr = new ProgressDialog(
|
|
|
context,
|
|
|
type: ProgressDialogType.Download,
|
|
|
isDismissible: true,
|
|
|
showLogs: true,
|
|
|
);
|
|
|
pr.style(message: '准备下载...');
|
|
|
if (!pr.isShowing()) {
|
|
|
pr.show();
|
|
|
}
|
|
|
|
|
|
final path = await _apkLocalPath;
|
|
|
await FlutterDownloader.enqueue(
|
|
|
//url: 'http://update.rwworks.com:8088/appManager/monitor/app/appload/' + appId + '',
|
|
|
url: _mapVer['downurl'],
|
|
|
savedDir: path,
|
|
|
fileName: apkName,
|
|
|
showNotification: true,
|
|
|
openFileFromNotification: true);
|
|
|
}
|
|
|
|
|
|
/// 下载进度回调函数
|
|
|
static void _downLoadCallback(String id, DownloadTaskStatus status, int progress) {
|
|
|
final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
|
|
|
send.send([id, status, progress]);
|
|
|
}
|
|
|
|
|
|
/// 更新下载进度框
|
|
|
_updateDownLoadInfo(dynamic data) {
|
|
|
DownloadTaskStatus status = data[1];
|
|
|
int progress = data[2];
|
|
|
if (status == DownloadTaskStatus.running) {
|
|
|
pr.update(progress: double.parse(progress.toString()), message: "下载中,请稍后…");
|
|
|
}
|
|
|
if (status == DownloadTaskStatus.failed) {
|
|
|
if (pr.isShowing()) {
|
|
|
pr.hide();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (status == DownloadTaskStatus.complete) {
|
|
|
if (pr.isShowing()) {
|
|
|
pr.hide();
|
|
|
}
|
|
|
_installApk();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// 安装apk
|
|
|
Future<Null> _installApk() async {
|
|
|
await OpenFile.open(appPath + '/' + apkName);
|
|
|
}
|
|
|
|
|
|
/// 获取apk存储位置
|
|
|
Future<String> get _apkLocalPath async {
|
|
|
final directory = await getExternalStorageDirectory();
|
|
|
String path = directory.path + Platform.pathSeparator + 'Download';
|
|
|
;
|
|
|
final savedDir = Directory(path);
|
|
|
bool hasExisted = await savedDir.exists();
|
|
|
if (!hasExisted) {
|
|
|
await savedDir.create();
|
|
|
}
|
|
|
this.setState(() {
|
|
|
appPath = path;
|
|
|
});
|
|
|
return path;
|
|
|
}
|
|
|
}
|