彻底解决Flutter_downloader中出现的问题

如果本文未能解决你的插件问题,请查看文章最底部另外一款插件的使用

由于之前已经发布过一篇文章Flutter内部更新遗留了一些问题就是关于Flutter_downloader报错的问题,错误原因是

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_xml


一开始挺摸不着头脑的,最近新的项目又涉及到了FlutterAPP内部更新问题,因为上次的失败,所以这次决定一定要解决掉,虽然又是和上次一样报了

'package:flutter_downloader/src/downloader.dart': Failed assertion: line 388 pos 12: 'callbackHandle != null'

开始检查代码和项目,首先发现第一个问题,状态栏已经触发下载方法了,但是状态为failed,也就是说明,插件的下载方法没有问题,但是没有下载成功。这是为什么呢??

错误原因:

由于我是用的本地映射网络,HTTP的请求下载方法,因为Android和IOS都有限制,禁止随便下载HTTP和访问HTTP的内容,具体原因和Flutter内部访问WebView出现net:ERR_CLEARTEXT_NOT_PERMITTED原因一致,所以只需要配置允许HTTP请求访问即可。

解决办法:

1、打开你的项目,在android/app/src/main/res目录下创建目录xml,随后创建xml文件network_security_config.xml

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_xml_02


具体代码

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

2、打开你的AndroidManifest.xml这个配置文件,加上下面这一行

android:networkSecurityConfig="@xml/network_security_config"

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_downloader_03

这个问题便可以解决了。

第二个问题

'callbackHandle != null'的错误原因

其本质原因就在于之前写监听下载方法registerCallback的时候忽略了文档上的这个要求,并且没有声明为static静态方法,所以才会导致这个问题的出现。

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_Flutter内部更新_04

解决办法

只需要将方法抽离出来,并且声明为静态方法便可以了。

@override
  void initState() { 
    super.initState();
    // clear();
    judgePhoneInfo();
    _checkPermission();
    createFile();
    
    FlutterDownloader.registerCallback(downloadCallback);
  }

// id:下载id status:下载状态 progress:下载进度
// 可用DownloadTaskStatus.failed == status 与 DownloadTaskStatus.complete == status 来判断失败与完成
  static void downloadCallback(id, status, progress){
    print('Download task ($id) is in status ($status) and process ($progress)');    
  }

下图为监听进度

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_HTTP_05


这样所有问题便可以得到解决了。

flutter app ios 在首次安装时 wifi状态下 无网络权限申请 flutter downloader_Flutter内部更新_06


2022.5.30更新

换插件了兄弟们! Flutter_downloader不行的,可以使用另外一款插件ota_update

亲测好用!!
使用方法:

/// 检查当前版本是否为最新,若不是,则更新
  void _checkVersionCode() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    api.getData(context, 'upgrade_init').then((v) {
      if (v != null) {
        String version = packageInfo.version;
        // v['data']['version'] 为后端返回的最新版本
        var isUpdate = haveNewVersion(v['data']['version'], version);
        if (isUpdate) {
         // v['data']['path'] 为后端返回的服务器apk路径
          _showNewVersionAppDialog(v['data']['path']);
        }
      }
    });
  }
  
  // 比较版本号判断是否更新
  bool haveNewVersion(String newVersion, String old) {
    if (newVersion == null || newVersion.isEmpty || old == null || old.isEmpty)
      return false;
    int newVersionInt, oldVersion;
    var newList = newVersion.split('.');
    var oldList = old.split('.');
    if (newList.length == 0 || oldList.length == 0) {
      return false;
    }
    for (int i = 0; i < newList.length; i++) {
      newVersionInt = int.parse(newList[i]);
      oldVersion = int.parse(oldList[i]);
      if (newVersionInt > oldVersion) {
        return true;
      } else if (newVersionInt < oldVersion) {
        return false;
      }
    }

    return false;
  }
  
/// 版本更新提示对话框
  Future<void> _showNewVersionAppDialog(path) async {
    // 显示提醒更新UI界面, 读者自行开发一下哈~
    return UpdateWidget(path);
  }

/// 执行更新操作

// 接收的path是UI界面中传入的path
  static doUpdate(BuildContext context, path) async {
    try {
        // destinationFilename 是对下载的apk进行重命名
        var destinationFilename = path.toString().substring(path.toString().lastIndexOf('/') + 1);

        
        OtaUpdate().execute(
          path,
          destinationFilename: destinationFilename,
          // headers:{},
        ).listen(
          (OtaEvent event) {
            try{
              switch (event.status) {
                case OtaStatus.DOWNLOADING: // 下载中
                  print('status:${event.status},value:${event.value}');
                  break;
                case OtaStatus.INSTALLING: //安装中=
                  break;
                case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 权限错误
                  break;
                default: // 其他问题
                  break;
              }
            }catch(e){
              print('错误:$e');
            }
          },
        );
      } catch (e) {
        print('更新失败');
      }
  }

有问题请在下方留言~