flutter APP自动更新
flutter APP自动更新前言在pubspec.yaml中安装依赖在main.dart文件中,初始化FlutterDownLoader配置网络在AndroidManifest.xml新增如下配置在项目入口dart文件中,新增自动更新逻辑代码效果图前言近期做flutter APP框架的搭建封装,在APP自动更新这块,参考了很多网址,但都不全面;故自己动手封装了一套,主要采用flutter_dow
·
flutter APP自动更新
前言
近期做flutter APP框架的搭建封装,在APP自动更新这块,参考了很多网址,但都不全面;故自己动手封装了一套,主要采用flutter_downloader及progress_dialog等;在APP启动成功后,若有最新版本,便会自动弹框提示是否更新,若更新,将会下载最新APP,并显示下载进度,下载完成后,将自动提示是否安装最新包。
此功能主要针对android APP自动更新
在pubspec.yaml中安装依赖
permission_handler: 5.0.0+hotfix.4
package_info: 0.4.1
path_provider: 1.6.11
open_file: 3.0.1
flutter_downloader: 1.5.0
progress_dialog: 1.2.0
在控制台输入 flutter packages get 命令,下载依赖包
在main.dart文件中,初始化FlutterDownLoader
...
import 'package:flutter_downloader/flutter_downloader.dart';
...
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true
);
runApp(MyApp());
}
....
配置网络
在android/app/src/main/res目录下,新建文件夹xml,在xml文件夹下,新增network_security_config.xml
在network_security_config.xml中写入以下代码
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
如下图:
在AndroidManifest.xml新增如下配置
- 新增权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
- 在<application …>中新增network_security_config配置
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter助手"
android:icon="@mipmap/ic_launcher"
android:networkSecurityConfig="@xml/network_security_config"
>
如下图:
3. 在<application …>标签内加入以下代码
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
android:authorities="${applicationId}.flutter_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:enabled="false"
android:exported="false" />
<provider
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
android:authorities="${applicationId}.flutter-downloader-init"
android:exported="false">
<!-- changes this number to configure the maximum number of concurrent tasks -->
<meta-data
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
android:value="5" />
</provider>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"
tools:replace="android:resource" />
</provider>
如下图:
在项目入口dart文件中,新增自动更新逻辑代码
- 导入相关包
import 'dart:isolate';
import 'dart:ui';
import 'dart:async';
import 'dart:io';
import 'package:package_info/package_info.dart';
import 'package:path_provider/path_provider.dart';
import 'package:open_file/open_file.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:progress_dialog/progress_dialog.dart';
- 声明变量
String serviceVersionCode = '';
String appId = '';
ProgressDialog pr;
String apkName ='app-release.apk';
String appPath = '';
ReceivePort _port = ReceivePort();
-
在initState中初始化
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port'); _port.listen(_updateDownLoadInfo); FlutterDownloader.registerCallback(_downLoadCallback);
-
判断,自动更新
@override
void afterFirstLayout(BuildContext context) {
// 如果是android,则执行热更新
if(Platform.isAndroid){
_getNewVersionAPP(context);
}
}
- 自动更新代码
/// 执行版本更新的网络请求
_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 + '',
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;
}
效果图
更多推荐
已为社区贡献5条内容
所有评论(0)