Flutter download sample method for updating App

  • 2021-11-10 10:44:58
  • OfStack

1. Description

iOS and Android updates are completely different.

iOS can only jump to AppStore, which is better to implement

Android needs to download apk package. Because there are many Android models, here we use dart to connect with the native android download library of the third party (here).

The update interface is handled separately from downloading updates.

iOS has no download progress, while Android has.

2. Code

2.1 iOS simply adopt url_launcher


if (Platform.isIOS) {
 final url = "https://itunes.apple.com/cn/app/id1380512641"; // id  Replace the following numbers with your own application  id  Just do it 
 if (await canLaunch(url)) {
  await launch(url, forceSafariVC: false);
 } else {
  throw 'Could not launch $url';
 }
}

2.1 Android Implementation

2.1. 1 Add a download library to the android/app/build. gradle file


dependencies {
  //  Copy only this 1 Row 
  implementation 'com.king.app:app-updater:1.0.4-androidx'
}

2.1. 2 Adding storage permissions on AndroidManifest. xml


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

2.1. 3 Writing plug-ins in the android project


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 Errors ", o);
   return;
  }
  if (!o.toString().startsWith("http")){
   eventSink.error(TAG, "URL Errors ", o);
  }

  AppUpdater update = new AppUpdater(context,o.toString()).setUpdateCallback(new UpdateCallback() {

   Map data = new HashMap<String, Object>();

   //  Send data to  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, " Cancel the download - Integrated number 3 Cancel method is not provided for party download ");
 }
}

2.1. 4 Register plug-ins in MainActivity


//  Register Update Component   In onCreate Method 
UpdateVersionPlugin.registerWith(registrarFor("iwubida.com/update_version"));

We need to get the download progress, so we use EventChannel for continuous one-way communication.

2.3 dart side implementation


static const channelName = 'plugins.iwubida.com/update_version';
 static const stream = const EventChannel(channelName);
 //  Progress subscription 
 StreamSubscription downloadSubscription;
 int percent = 0;
 
  //  Start downloading 
 void _startDownload() {
  if (downloadSubscription == null) {
   downloadSubscription = stream
     .receiveBroadcastStream(widget.data.apkUrl)
     .listen(_updateDownload);
  }
 }

 //  Stop listening for progress 
 void _stopDownload() {
  if (downloadSubscription != null) {
   downloadSubscription.cancel();
   downloadSubscription = null;
   percent = 0;
  }
 }

 //  Progress download 
 void _updateDownload(data) {
  int progress = data["percent"];
  if (progress != null) {
   setState(() {
    percent = progress;
   });
  }
 }
 

2.4 Others

In addition, Android still has the problem of permission application. You can refer to the code in the following project.

https://github.com/xushengjiang0/flutter_yuedu

dart code: lib/widget/update_version. dart


Related articles: