最新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('更新失败,请稍后再试');
      }
    }
  }

好了,全部的代码都在这里了,如果有什么问题,请给我留言!

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