彻底解决Flutter_downloader中出现的问题

彻底解决Flutter_downloader中出现的问题

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

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

在这里插入图片描述
一开始挺摸不着头脑的,最近新的项目又涉及到了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
在这里插入图片描述
具体代码

<?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"

在这里插入图片描述

这个问题便可以解决了。

第二个问题

'callbackHandle != null'的错误原因

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

解决办法

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

 @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)');    
  }

下图为监听进度
在这里插入图片描述
这样所有问题便可以得到解决了。在这里插入图片描述


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('更新失败');
      }
  }

有问题请在下方留言~

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
flutter_downloader是一个用于在Flutter应用程序进行文件下载的插件。它提供了一种简单而强大的方式来管理和监控文件下载任务。 使用flutter_downloader,你可以轻松地添加文件下载功能到你的Flutter应用程序。它支持多个平台,包括Android和iOS,并且提供了一组易于使用的API来管理下载任务。 要使用flutter_downloader,首先需要在你的Flutter项目添加依赖。在pubspec.yaml文件,添加以下内容: ``` dependencies: flutter_downloader: ^1.6.0 ``` 然后运行`flutter pub get`命令来获取依赖。 接下来,在你的代码导入flutter_downloader包,并使用它来创建和管理下载任务。你可以使用`FlutterDownloader.enqueue`方法来创建一个下载任务,并传递下载链接、保存路径等参数。你还可以使用`FlutterDownloader.open`方法来打开已下载的文件。 以下是一个简单的示例代码,演示了如何使用flutter_downloader进行文件下载: ```dart import 'package:flutter/material.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('File Downloader'), ), body: Center( child: RaisedButton( child: Text('Download File'), onPressed: () { _startDownload(); }, ), ), ), ); } void _startDownload() async { String url = 'https://example.com/file.pdf'; String savedDir = '/storage/emulated/0/Download'; await FlutterDownloader.enqueue( url: url, savedDir: savedDir, showNotification: true, openFileFromNotification: true, ); } } ``` 这是一个简单的示例,当用户点击按钮时,会触发文件下载任务。下载的文件将保存在指定的目录,并且会显示下载通知。用户可以通过通知来打开已下载的文件。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值