|
|
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_ybqx511505_sanjiang_new_area_launche/components/dioFun.dart';
|
|
|
import 'package:open_file/open_file.dart';
|
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
import 'package:progress_dialog/progress_dialog.dart';
|
|
|
|
|
|
import '../../../components/commonFun.dart';
|
|
|
|
|
|
///版本更新类
|
|
|
class MyUpdatedNew {
|
|
|
MyUpdatedNew(
|
|
|
{this.ver,
|
|
|
this.date,
|
|
|
this.theContext,
|
|
|
this.bStartUpdated = false,
|
|
|
this.bShowNoNewVersion = false}) {
|
|
|
initState();
|
|
|
}
|
|
|
|
|
|
String ver = '1.0.0';
|
|
|
String date = '';
|
|
|
BuildContext theContext;
|
|
|
bool bStartUpdated;
|
|
|
bool bShowNoNewVersion;
|
|
|
|
|
|
//2、声明变量
|
|
|
int _stampAppCompile = -1;
|
|
|
String _dateNewver = '';
|
|
|
Map _mapVer = {};
|
|
|
String serviceVersionCode = '';
|
|
|
String appId = '';
|
|
|
ProgressDialog pr;
|
|
|
String apkName = '';
|
|
|
String appPath = '';
|
|
|
ReceivePort _port = ReceivePort();
|
|
|
|
|
|
void initState() {
|
|
|
// 0、初始化FlutterDownLoader。版本更新初始化,放在这里会报错,初始化失败
|
|
|
// WidgetsFlutterBinding.ensureInitialized();
|
|
|
if (!bFlutterDownloader_initialize) {
|
|
|
FlutterDownloader.initialize(debug: true).then((value) {
|
|
|
registerCallback(first: true);
|
|
|
});
|
|
|
} else {
|
|
|
registerCallback();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
registerCallback({bool first = false}) {
|
|
|
//3、在initState中初始化
|
|
|
/*
|
|
|
D/DownloadWorker( 4745): Update too frequently!!!!, this should be dropped
|
|
|
E/flutter ( 4745): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'update' was called on null.
|
|
|
E/flutter ( 4745): Receiver: null
|
|
|
E/flutter ( 4745): Tried calling: update(message: "下载中,请稍后…", progress: 0.0)
|
|
|
E/flutter ( 4745): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
|
|
|
E/flutter ( 4745): #1 MyUpdatedNew._updateDownLoadInfo (package:hyzp_ybqx511505_sanjiang_new_area_launche/pages/MyMsics/05_updated/MyUpdatedNew.dart:251:10)
|
|
|
E/flutter ( 4745): #2 _rootRunUnary (dart:async/zone.dart:1206:13)
|
|
|
E/flutter ( 4745): #3 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
|
|
|
E/flutter ( 4745): #4 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
|
|
|
E/flutter ( 4745): #5 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
|
|
|
E/flutter ( 4745): #6 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
|
|
|
E/flutter ( 4745): #7 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
|
|
|
E/flutter ( 4745): #8 _StreamController._add (dart:async/stream_controller.dart:682:7)
|
|
|
E/flutter ( 4745): #9 _StreamController.add (dart:async/stream_controller.dart:624:5)
|
|
|
E/flutter ( 4745): #10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
|
|
|
E/flutter ( 4745):
|
|
|
*/
|
|
|
|
|
|
if (!first) {
|
|
|
// 解决2次进入报错无法下载的问题-OK
|
|
|
// 如果以前注册过必须先移除,否则报错无法下载:DownloadWorker( 4745): Update too frequently!!!!, this should be dropped
|
|
|
IsolateNameServer.removePortNameMapping('downloader_send_port');
|
|
|
// FlutterDownloader.cancelAll();
|
|
|
// FlutterDownloader.remove(taskId: null);
|
|
|
}
|
|
|
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 = ${ver}');
|
|
|
//_mapVer['ver'] = '1.3.1';
|
|
|
print('newVer = ${_mapVer['ver']}');
|
|
|
// I/flutter ( 1872): oldVer = 1.3.0
|
|
|
// I/flutter ( 1872): newVer = 1.3.1
|
|
|
|
|
|
if (first) {
|
|
|
bFlutterDownloader_initialize = true;
|
|
|
}
|
|
|
|
|
|
startUpdated();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
///开始更新过程
|
|
|
Future startUpdated() async {
|
|
|
// 如果是android,则执行热更新
|
|
|
if (Platform.isAndroid) {
|
|
|
verCompare(newVer: _mapVer['ver'], oldVer: ver).then((value) {
|
|
|
if (value) {
|
|
|
print('value = $value');
|
|
|
//_getNewVersionAPP(context);
|
|
|
//appId = res.data['id'];
|
|
|
//_checkVersionCode();
|
|
|
bNewVer = true; //发现新版本
|
|
|
if (bStartUpdated) {
|
|
|
serviceVersionCode = _mapVer['ver'];
|
|
|
_showNewVersionAppDialog();
|
|
|
}
|
|
|
} else if (bShowNoNewVersion) {
|
|
|
// 没有发现新版本
|
|
|
_showNoNewVersionAppDialog();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// 没有发现新版本
|
|
|
Future<void> _showNoNewVersionAppDialog() async {
|
|
|
return showDialog<void>(
|
|
|
context: theContext,
|
|
|
barrierDismissible: false,
|
|
|
builder: (BuildContext context) {
|
|
|
return AlertDialog(
|
|
|
title: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: <Widget>[Text("没有发现新版本")],
|
|
|
),
|
|
|
content: Container(
|
|
|
//padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
|
|
|
height: ScreenUtil().setHeight(230),
|
|
|
decoration: BoxDecoration(
|
|
|
border: Border.all(color: Colors.blueAccent, width: 1.0),
|
|
|
borderRadius: BorderRadius.circular(5),
|
|
|
),
|
|
|
alignment: Alignment.center,
|
|
|
child: RichText(
|
|
|
textAlign: TextAlign.center,
|
|
|
text: TextSpan(children: [
|
|
|
TextSpan(text: 'NewVer: ', style: TextStyle(fontSize: 17, color: Colors.black)),
|
|
|
TextSpan(
|
|
|
text: '暂无新版本',
|
|
|
style: TextStyle(
|
|
|
fontSize: 17, color: Colors.black, fontWeight: FontWeight.bold)),
|
|
|
]),
|
|
|
),
|
|
|
),
|
|
|
actions: <Widget>[
|
|
|
new FlatButton(
|
|
|
child: new Text('确定'),
|
|
|
onPressed: () {
|
|
|
Navigator.of(context).pop();
|
|
|
},
|
|
|
),
|
|
|
],
|
|
|
);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// 版本更新提示对话框
|
|
|
Future<void> _showNewVersionAppDialog() async {
|
|
|
String content1 = "注意:";
|
|
|
String content2 = "新版本下载成功后,将弹出“安装未知应用程序”界面,请";
|
|
|
String content3 = "授权“允许此来源”";
|
|
|
String content4 = ";然后";
|
|
|
String content5 = "稍等几秒钟";
|
|
|
String content6 = ",再";
|
|
|
String content7 = "点击“返回”按钮(一般位于左上角)";
|
|
|
String content8 = ",按照提示即可完成升级过程。若";
|
|
|
String content9 = "升级过程意外中断";
|
|
|
String content10 = ",可重启App再次升级即可。";
|
|
|
|
|
|
return showDialog<void>(
|
|
|
context: theContext,
|
|
|
barrierDismissible: false,
|
|
|
builder: (BuildContext context) {
|
|
|
return AlertDialog(
|
|
|
insetPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 24.0),
|
|
|
buttonPadding: EdgeInsets.only(bottom: 15, right: 20),
|
|
|
title: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: <Widget>[Text("发现新版本")],
|
|
|
),
|
|
|
content: Container(
|
|
|
padding: EdgeInsets.only(
|
|
|
left: ScreenUtil().setHeight(25), right: ScreenUtil().setHeight(10)),
|
|
|
height: ScreenUtil().setHeight(620),
|
|
|
decoration: BoxDecoration(
|
|
|
border: Border.all(color: Colors.blueAccent, width: 1.0),
|
|
|
borderRadius: BorderRadius.circular(5),
|
|
|
),
|
|
|
alignment: Alignment.center,
|
|
|
child: Column(
|
|
|
children: [
|
|
|
RichText(
|
|
|
textAlign: TextAlign.center,
|
|
|
text: TextSpan(children: [
|
|
|
TextSpan(
|
|
|
text: '\nNewVer: ',
|
|
|
style: TextStyle(fontSize: 17, color: Colors.redAccent)),
|
|
|
TextSpan(
|
|
|
text: serviceVersionCode,
|
|
|
style: TextStyle(
|
|
|
fontSize: 17, color: Colors.redAccent, fontWeight: FontWeight.bold)),
|
|
|
]),
|
|
|
),
|
|
|
RichText(
|
|
|
textAlign: TextAlign.justify,
|
|
|
text: TextSpan(children: [
|
|
|
getTextSpan('\n' + content1, color: Colors.blueAccent),
|
|
|
getTextSpan(content2),
|
|
|
getTextSpan(content3, color: Colors.redAccent),
|
|
|
getTextSpan(content4),
|
|
|
getTextSpan(content5, color: Colors.redAccent),
|
|
|
getTextSpan(content6),
|
|
|
getTextSpan(content7, color: Colors.redAccent),
|
|
|
getTextSpan(content8),
|
|
|
getTextSpan(content9, color: Colors.blueAccent),
|
|
|
getTextSpan(content10),
|
|
|
]),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
actions: <Widget>[
|
|
|
new FlatButton(
|
|
|
child: new Text('立即更新'),
|
|
|
onPressed: () {
|
|
|
/// 执行更新操作
|
|
|
Navigator.pop(context);
|
|
|
_executeDownload(context);
|
|
|
},
|
|
|
),
|
|
|
new FlatButton(
|
|
|
child: new Text('下次再说'),
|
|
|
onPressed: () {
|
|
|
Navigator.of(context).pop();
|
|
|
},
|
|
|
),
|
|
|
],
|
|
|
);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
TextSpan getTextSpan(String _text, {Color color = Colors.black, double fontSize = 15}) {
|
|
|
return TextSpan(text: _text, style: TextStyle(fontSize: fontSize, color: color));
|
|
|
}
|
|
|
|
|
|
/// 下载最新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;
|
|
|
apkName = getFileName(_mapVer['downurl']);
|
|
|
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();
|
|
|
}
|
|
|
appPath = path;
|
|
|
|
|
|
// this.setState(() {
|
|
|
// appPath = path;
|
|
|
// });
|
|
|
|
|
|
return path;
|
|
|
}
|
|
|
|
|
|
//4、判断,自动更新
|
|
|
// 版本比较
|
|
|
//R:\FlutterProject\FlutterProject33\hyzp_ybqx\lib\pages\MyMsics\05_updated\MyUpdatedNew.dart line 343
|
|
|
Future verCompare({String newVer, String oldVer}) async {
|
|
|
//解决newVer中不包含字符“+”号报错失败问题
|
|
|
if (newVer.indexOf('+') > -1) {
|
|
|
//解决App.Car_Ver.Getver接口返回值变化后,1.3.11+20210729字符串转换为数字报错问题
|
|
|
print('newVer = $newVer');
|
|
|
newVer = newVer.substring(0, newVer.indexOf('+')); // substring是含头不含尾
|
|
|
print('newVer2 = $newVer');
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
|
|
|
//5、自动更新代码
|
|
|
/// 执行版本更新的网络请求
|
|
|
|
|
|
/// 检查当前版本是否为最新,若不是,则更新
|
|
|
// 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();
|
|
|
// }
|
|
|
// });
|
|
|
// }
|
|
|
}
|