阅读 1297

Flutter下载更新 App

1. 说明

  1. iOS 和Android 更新是完全不一样的。

  2. iOS 只能跳转到 AppStore,比较好实现

  3. Android则需要下载apk包,由于Android机型较多,这里我们用 dart 连接第三方的原生 Android 下载库。

  4. 更新界面和下载更新分开处理的。

  5. iOS 没得下载进度这一说,Android 则有。

screen

2. 代码

2.1 iOS 直接采用url_launcher打开 AppStore就可以了

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 文件添加下载库
dependencies {
    // 只复制这一行
    implementation 'com.king.app:app-updater:1.0.4-androidx'
}
复制代码
2.1.2 在 AndroidManifest.xml添加存储权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
复制代码
2.1.3 在 Android 项目中编写插件
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);
      return;
    }

    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", false);
        data.put("done", false );
        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 中注册插件
// 注册更新组件 在onCreate方法中
UpdateVersionPlugin.registerWith(registrarFor("iwubida.com/update_version"));
复制代码

我们需要获取到下载进度,所以我们采用EventChannel来持续单向通讯。

2.3 dart端实现

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 还有权限申请的问题。可以参考下面项目中的代码。

项目源码

位置: lib/widget/update_version.dart

关注下面的标签,发现更多相似文章
评论