Flutter做的App怎么自动更新呢 首先要用到两个依赖一个叫update_app
另外一个叫package_info
还有一个叫Dio
一个是用来下载App的 一个是用来获取当前App的版本信息的 一个是用来网络链接的
flutter pub add update_app
flutter pub add package_info
flutter pub add dio
然后上代码
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:update_app/bean/download_process.dart';
import 'package:update_app/update_app.dart';
void main() => runApp(MyApp());
//为什么我要先用StatelessWidget 再用StatefulWidget 的呢 因为如果不这样 会报错误 找不到父类的祖宗Context
class MyApp extends StatelessWidget {
_MyAppState createState() => _MyAppState();
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(), // here pass parameter
);
}
}
class HomePage extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<HomePage> {
//定时更新进度
Timer? timer;
//下载进度
double downloadProcess = 0;
//下载状态
String downloadStatus = "";
void initState() {
super.initState();
SchedulerBinding.instance!.addPostFrameCallback((_) => {ifUpdate(context)});
}
Future<void> ifUpdate(BuildContext buildContext) async {
var s = "http://你的后端链接获取你设置App的版本号";
var dio = Dio();
final response = await dio.get(s);
print(response.data);
PackageInfo packageInfo = await PackageInfo.fromPlatform();
//如果你设置的版本号 于你本机上的App的版本号 不一致 弹出下载框
if (response.data != packageInfo.version) {
print(packageInfo.version);
updatedialog.showUpdateDialog(buildContext, '有新版本发布\n2.请更新', false);
}
}
Widget build(BuildContext? context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Update app'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.all(16),
width: 200,
height: 200,
child: CircularProgressIndicator(
value: downloadProcess,
strokeWidth: 10,
),
),
Text("Download status: $downloadStatus"),
Text("Please replace the download url with your own address"),
],
),
),
bottomNavigationBar: Container(
padding: EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'点击右下角的下载按钮下载!',
style: TextStyle(color: Theme.of(context!).primaryColor),
),
],
)),
floatingActionButton: FloatingActionButton(
onPressed: download,
child: Icon(Icons.file_download),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
),
);
}
void dispose() {
timer?.cancel();
super.dispose();
}
void download() async {
var downloadId = await UpdateApp.updateApp(
url:
"https://你app的下载地址",
);
//本地已有一样的apk, 下载成功
if (downloadId == 0) {
setState(() {
downloadProcess = 1;
downloadStatus = ProcessState.STATUS_SUCCESSFUL.toString();
});
return;
}
//出现了错误, 下载失败
if (downloadId == -1) {
setState(() {
downloadProcess = 1;
downloadStatus = ProcessState.STATUS_FAILED.toString();
});
return;
}
//正在下载文件
timer = Timer.periodic(Duration(milliseconds: 100), (timer) async {
var process = await UpdateApp.downloadProcess(downloadId: downloadId);
//更新界面状态
setState(() {
downloadProcess = process.current / process.count;
downloadStatus = process.status.toString();
});
if (process.status == ProcessState.STATUS_SUCCESSFUL ||
process.status == ProcessState.STATUS_FAILED) {
//如果已经下载成功, 取消计时
timer.cancel();
}
});
}
}
下面是弹窗widgt 你们可以自己修改 或者自己写一个
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:translateapp/CommonUtils/toast_helper.dart';
import 'package:translateapp/main.dart';
///update by zah
///on 2023/1/7
///description:版本更新提示弹窗
class updatedialog extends Dialog {
final String upDateContent = "";
final bool isForce = false;
updatedialog({Key? key, required String upDateContent, required bool isForce})
: super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
/* decoration: BoxDecoration(
color: backgroundColor,
border: Border.all(color: Colors.white60),
shape: BoxShape.circle,
),*/
width: MediaQuery.of(context).size.width -
(MediaQuery.of(context).size.width / 4),
/* height: ,*/
child: Stack(
children: <Widget>[
/* Image.asset(
AssetsUtil.getImagePath(
imageName: 'bg_update', suffix: 'png'),
fit: BoxFit.cover,
),*/
Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 10),
child: const Text('发现新版本',
style: TextStyle(
fontSize: 14,
color: Colors.white,
decoration: TextDecoration.none)),
),
Text(upDateContent,
style: TextStyle(
fontSize: 14,
color: Colors.black54,
decoration: TextDecoration.none)),
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(bottom: 10),
child: RaisedButton(
color: Colors.red,
shape: StadiumBorder(),
child: Text(
'立即更新',
style: TextStyle(
fontSize: 14, color: Colors.white),
),
onPressed: () {
HomePage home = new HomePage();
home.createState().download();
Navigator.pop(context);
}),
)
],
),
),
],
),
),
GestureDetector(
onTap: () {
exit(0);
},
child: Offstage(
offstage: isForce,
child: Container(
margin: EdgeInsets.only(top: 10),
child: Icon(
Icons.cancel,
size: 54,
color: Colors.white,
),
/* Image.asset(
AssetsUtil.getImagePath(
imageName: 'ic_update_close', suffix: 'png'),
width:100 ,
height: ,100
)*/
),
),
)
],
),
),
);
}
static showUpdateDialog(
BuildContext context, String mUpdateContent, bool mIsForce) {
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return WillPopScope(
child: updatedialog(
upDateContent: mUpdateContent, isForce: mIsForce),
onWillPop: _onWillPop);
});
}
static Future<bool> _onWillPop() async {
return false;
}
}
效果如下
对了 最后 还有一点 下载的文件 如果它不安装 直接把它下载的文件删掉 由于依赖没有这个方法 我自己加了下去 就一句代码而已