一、前言
我们平时开发原生应用时有新版本发布都会有版本升级提示,然后引导客户去下载更新版本,iOS一般的做法是跳转到AppStore更新,Android的处理办法要么是商店更新,要么是应用内直接下载安装更新,因为第一次用Flutter开发应用,所以碰到了这个更新的问题,网上也没有找到写的特别详细简洁的处理办法,最后经过一番努力做好了版本升级,感觉做的还可以,所以这里做次记录,希望能帮到有需要的人。
本文iOS是跳转到AppStore更新,Android是应用内下载,下载完毕后跳转安装
二、效果图
三、升级逻辑
- 请求版本升级接口
接口返回数据应该有下面这些,在拿到接口数据的版本号后和本地版本号对比,如果接口版本号大于本地版本号则提示升级
1-版本号
// 或者将本地版本号传给后台,后台进行对比返回是否升级
version_code: 1.0.0,
2-下载地址
ios_download_url: itms-apps://itunes.apple.com/cn/app/id1480944644?mt=8,
android_download_url: http://xxx.com/xxx-release.apk,
3-升级文案
content: 1.性能优化 2.问题修复,
四、具体升级方案
####1、 使用到的三方库
- PackageInfo:获取版本号
- ota_update:支持Android应用内下载,实现应用内更新功能
- url_launcher:网页打开工具,适用于iOS版本更新,可以打开应用地址,跳转AppStore更新
2、主要代码
import 'package:flutter/material.dart';
import 'package:package_info/package_info.dart';
import 'dart:io';
import 'package:url_launcher/url_launcher.dart';
import 'package:ota_update/ota_update.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String vInfo = '';
String progress = '';
@override
void initState() {
super.initState();
_initData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('版本升级'),
),
body: Container(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
color: Colors.black38,
onPressed: _updateVersion,
child: Text('版本升级')
),
Container(
child: Text('$vInfo'),
),
Container(
child: Text('$progress'),
),
],
),
),
);
}
void _initData() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String version = packageInfo.version;
setState(() {
vInfo = Platform.isIOS ? 'iOS_$version' : 'android_$version';
});
}
void _updateVersion() async{
if (Platform.isIOS){
String url = 'itms-apps://itunes.apple.com/cn/app/id414478124?mt=8'; // 这是微信的地址,到时候换成自己的应用的地址
if (await canLaunch(url)){
await launch(url);
}else {
throw 'Could not launch $url';
}
}else if (Platform.isAndroid){
String url = 'http://3g.163.com/links/4636'; // 网易新闻下载地址,地址可能失效,在测试时候可以先确认下下载地址是否是有效的
try {
// destinationFilename 是对下载的apk进行重命名
OtaUpdate().execute(url, destinationFilename: 'news.apk').listen(
(OtaEvent event) {
print('status:${event.status},value:${event.value}');
switch(event.status){
case OtaStatus.DOWNLOADING: // 下载中
setState(() {
progress = '下载进度:${event.value}%';
});
break;
case OtaStatus.INSTALLING: //安装中
break;
case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 权限错误
print('更新失败,请稍后再试');
break;
default: // 其他问题
break;
}
},
);
} catch (e) {
print('更新失败,请稍后再试');
}
}
}
}
五、注意事项
- 1、 ota_update 这个插件需要在AndroidManifest.xml中增加以下引用,具体的可以参考这个插件用法,但是 资源 xml/filepaths 这个文件插件中是不存在的,所以需要我们自己创建,具体创建步骤如下
上图为文件路径,创建一个xml文件夹,然后创建一个filepaths.xml文件,文件内容为
<paths>
<external-path
name="external-path"
path="."/>
<external-cache-path
name="external-cache-path"
path="."/>
<external-files-path
name="external-files-path"
path="."/>
<files-path
name="files_path"
path="."/>
<cache-path
name="cache-path"
path="."/>
<root-path
name="name"
path="."/>
</paths>
2020.7.8更新
ota_upage 插件已经更新,现在要传destinationFilename: 'news.apk'
apk的命名,但是很遗憾的是以前老的使用这个方法的应用无法自动更新了,只能重新下载,作者并没有做好兼容,这个很遗憾
最后附上Demo地址,如有什么不足和错误请指正,觉得受用反手就给颗🌟吧