1. 说明
iOS 和Android 更新是完全不一样的。
iOS 只能跳转到 AppStore,比较好实现
Android则需要下载apk包,由于Android机型较多,这里我们用 dart 连接第三方(这里)的原生 android 下载库。
更新界面和下载更新分开处理的。
iOS 没得下载进度这一说,Android 则有。
2. 代码
2.1 iOS 直接采用url_launcher就可以了
代码语言:javascript复制if (Platform.isIOS) {
final url = "https://itunes.apple.com/cn/app/id1380512641"; // id 后面的数字换成自己的应用 id 就行了
if (await canLaunch(url)) {
await launch(url, forceSafariVC: false);
} else {
throw 'Could not launch $url';
}
}
2.1 Android实现
2.1.1 在 android/app/build.gradle 文件添加下载库
代码语言:javascript复制dependencies {
// 只复制这一行
implementation 'com.king.app:app-updater:1.0.4-androidx'
}
2.1.2 在 AndroidManifest.xml添加存储权限
代码语言:javascript复制<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/
2.1.3 在 android 项目中编写插件
代码语言:javascript复制package com.iwubida.flutter_yuedu.plugins;
import android.content.Context;
import android.util.Log;
import com.king.app.updater.AppUpdater;
import com.king.app.updater.callback.UpdateCallback;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** UpdateVersionPlugin */
public class UpdateVersionPlugin implements EventChannel.StreamHandler {
private static String TAG = "MY_UPDATE";
private static Context context;
public UpdateVersionPlugin(Context context) {
this.context = context;
}
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final EventChannel channel = new EventChannel(registrar.messenger(), "plugins.iwubida.com/update_version");
channel.setStreamHandler(new UpdateVersionPlugin(registrar.context()));
}
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
if (o.toString().length() < 5) {
eventSink.error(TAG, "URL错误", o);
return;
}
if (!o.toString().startsWith("http")){
eventSink.error(TAG, "URL错误", o);
}
AppUpdater update = new AppUpdater(context,o.toString()).setUpdateCallback(new UpdateCallback() {
Map data = new HashMap<String, Object ();
// 发送数据到 Flutter
private void sendData() {
eventSink.success(data);
}
@Override
public void onDownloading(boolean isDownloading) {
}
@Override
public void onStart(String url) {
data.put("start", true);
data.put("cancel", true);
data.put("done", true);
data.put("error", false);
data.put("percent", 1);
sendData();
}
@Override
public void onProgress(int progress, int total, boolean isChange) {
int percent = (int)(progress * 1.0 / total * 100);
if (isChange && percent 0) {
data.put("percent", percent);
sendData();
}
}
@Override
public void onFinish(File file) {
data.put("done", true);
sendData();
}
@Override
public void onError(Exception e) {
data.put("error", e.toString());
sendData();
}
@Override
public void onCancel() {
data.put("cancel", true);
sendData();
}
});
update.start();
}
@Override
public void onCancel(Object o) {
Log.i(TAG, "取消下载-集成的第三方下载没有提供取消方法");
}
}
2.1.4 在 MainActivity 中注册插件
代码语言:javascript复制// 注册更新组件 在onCreate方法中
UpdateVersionPlugin.registerWith(registrarFor("iwubida.com/update_version"));
我们需要获取到下载进度,所以我们采用EventChannel来持续单向通讯。
2.3 dart端实现
代码语言:javascript复制static const channelName = 'plugins.iwubida.com/update_version';
static const stream = const EventChannel(channelName);
// 进度订阅
StreamSubscription downloadSubscription;
int percent = 0;
// 开始下载
void _startDownload() {
if (downloadSubscription == null) {
downloadSubscription = stream
.receiveBroadcastStream(widget.data.apkUrl)
.listen(_updateDownload);
}
}
// 停止监听进度
void _stopDownload() {
if (downloadSubscription != null) {
downloadSubscription.cancel();
downloadSubscription = null;
percent = 0;
}
}
// 进度下载
void _updateDownload(data) {
int progress = data["percent"];
if (progress != null) {
setState(() {
percent = progress;
});
}
}
2.4 其它
另外 Android 还有权限申请的问题。可以参考下面项目中的代码。
https://github.com/xushengjiang0/flutter_yuedu
dart 代码: lib/widget/update_version.dart
以上就是本文的全部内容,希望对大家的学习有所帮助。