最新FlutterAPP內部更新並且安裝的功能

前言:

介紹一下APP更新的流程
1 、Android App 升級執行流程
1、獲取本地版本號
2、請求服務器獲取服務器版本號
3、本地版本和服務器版本不一致提示升級,彈窗提示用戶是否更新
4、用戶確定升級,調用文件傳輸方法下載 apk 文件
5、監聽下載進度
6、下載完成打開 Apk 進行安裝
注意:在 Ios 中沒法直接下載安裝,如果版本不一致直接跳轉到 Ios 應用對應的應用市場就可以了

APP內部更新並且安裝是許多APP必備的功能,其中網上廣爲流傳的方法是利用以下4個插件來更新並安裝APP
package_info: ^0.4.0+4                       #檢測版本號
path_provider: ^1.1.0                         #文件路徑
open_file: ^2.0.3                             #打開文件
flutter_downloader: ^1.3.2                    #下載文件

這4個插件是最流行的,但是當我使用的時候,flutter_downloader卻出現了下面這個錯誤

Unhandled Exception: 'package:flutter_downloader/src/downloader.dart': Failed assertion: line 388 pos 12: 'callbackHandle != null': callback must be a top-level or a static function


後續追加內容

關於這個問題我已在徹底解決Flutter_downloader的問題一文中解決了,如果想要繼續使用Flutter_downloader的請點擊前往


在這裏給大家介紹另外一個下載Apk文件的插件:ota_update
pub地址:https://pub.dev/packages/ota_update
gitHub地址:https://github.com/4Q-s-r-o/ota_update

當然這個插件只是替換flutter_downloader用的,另外三個插件還是需要使用的。

準備工作:

1、首先打開你的AndroidManifest.xml,添加下面這些權限代碼

在這裏插入圖片描述

<provider
    android:name="sk.fourq.otaupdate.OtaUpdateFileProvider"
    android:authorities="${applicationId}.ota_update_provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths" />
</provider>

2、創建xml文件夾,並創建filepaths.xml文件

在這裏插入圖片描述
3、將代碼複製進去,就可以了

<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>
Flutter代碼

首先:在你需要判斷更新的頁面中引入你安裝的那4個插件

1
第一步裏面api.getData()是我封裝的請求方法,讀者在套用代碼的時候,可以更換爲自己的版本請求接口,

 //獲取版本號
  _getPackageInfo() async{
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    String appName = packageInfo.appName;
    String packageName = packageInfo.packageName;
    String version = packageInfo.version;
    String buildNumber = packageInfo.buildNumber;
    
    api.getData(context, 'update').then((val){
      print('-------------獲取版本信息--------------');
      var response = json.decode(val.toString());
      // 如果當前版本比服務器小,返回-1,大返回1,相等返回0
      var isUpdate = version.compareTo(response['version_no']);

      setState(() {
        app_url = '$base_url${response['app_path']}';
      });
      // 如果版本低於服務器版本就顯示更新提示
      if(isUpdate.toString() == '-1'){
        _showDialog();
      }
    });
    
    print("App名稱:${appName}");

    print("包名:${packageName}");

    print("version:${version}");
    
    print("打包次數:${buildNumber}");

  }
彈框在這裏我就不佔用地方給大家寫了,直接就貼出來下載的方法了
//下載並打開文件
  _downLoad()async {
  	// 獲取APP安裝路徑
     Directory appDocDir = await getApplicationDocumentsDirectory();
     String appDocPath = appDocDir.path;
     
    if (Platform.isIOS){
      String url = 'itms-apps://itunes.apple.com/cn/app/id414478124?mt=8'; //到時候換成自己的應用的地址
      // 通過url_launcher插件來跳轉AppStore
      // if (await canLaunch(url)){
      //   await launch(url);
      // }else {
      //   throw 'Could not launch $url';
      // }
    }else if (Platform.isAndroid){
      String url = app_url;
      // String url = "http://www.ionic.wang/jdshop.apk";
      print(url);
      try {
        OtaUpdate().execute(url).listen(
              (OtaEvent event) {
            print('status:${event.status},value:${event.value}');
            switch(event.status){
              case OtaStatus.DOWNLOADING: // 下載中
                setState(() {
                  progress = '下載進度:${event.value}%';
                });
                break;
              case OtaStatus.INSTALLING: //安裝中
                  print('-----安裝中----');
                  // 打開安裝文件
                  //這裏的這個Apk文件名可以寫,也可以不寫
                  //不寫的話會出現讓你選擇用瀏覽器打開,點擊取消就好了,寫了後會直接打開當前目錄下的Apk文件,名字隨便定就可以
                  OpenFile.open("${appDocPath}/new.apk");
                break;
              case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 權限錯誤
                print('更新失敗,請稍後再試');
                
                break;
              default: // 其他問題
                break;
            }
          },
        );
      } catch (e) {
        print('更新失敗,請稍後再試');
      }
    }
  }

好了,全部的代碼都在這裏了,如果有什麼問題,請給我留言!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章