繁体   English   中英

flutter_downloader 获得许多任务的进度

[英]flutter_downloader get progress for many tasks

我正在使用 Flutter_downloader package 开发下载管理器应用程序,它是唯一的 package,它为我们提供了很多选项,例如暂停、恢复、重试、取消、删除等等,但我面临的问题是进度问题。

我正在使用下载 model 文件来定义下载

import 'package:flutter/material.dart';

class Download {
  final String name;
  final String size;
  final String status;
  final String timeLeft;
  final String transferRate;
  final String type;
  final String path;
  final String icon;
  int progress;

  Download({
    @required this.name,
    @required this.size,
    @required this.status,
    @required this.timeLeft,
    @required this.transferRate,
    @required this.type,
    @required this.path,
    @required this.icon,
    @required this.progress,
  });
}

并下载提供程序文件以获取所有下载并处理所有下载操作

import 'dart:isolate';
import 'dart:ui';

import 'package:idminternetdownloadmanager/models/download.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:http/http.dart' as http;
import 'package:ext_storage/ext_storage.dart';

class DownloadsProvider with ChangeNotifier {
  List<Download> _downloads = [];

  List<Download> get downloads {
    return [..._downloads];
  }

  void addDownload(String url) async {
    var taskId;
    //set name
    final name = url.split('/').last;
    //set type
    final type = url.split('.').last;
    //set icon
    final icon = type == 'pdf'
        ? 'lib/assets/pdf.png'
        : type == 'txt'
            ? 'lib/assets/txt.png'
            : type == 'docx' || type == 'doc'
                ? 'lib/assets/doc.png'
                : type == 'zip' || type == 'rar'
                    ? 'lib/assets/rar.png'
                    : type == 'iso'
                        ? 'lib/assets/iso.png'
                        : type == 'tif' ||
                                type == 'jpg' ||
                                type == 'gif' ||
                                type == 'png' ||
                                type == 'raw'
                            ? 'lib/assets/png.png'
                            : type == 'flv' ||
                                    type == 'avi' ||
                                    type == 'mov' ||
                                    type == 'mpeg' ||
                                    type == 'mp4' ||
                                    type == 'ogg' ||
                                    type == 'wmv' ||
                                    type == 'webm' ||
                                    type == '3gp'
                                ? 'lib/assets/mp4.png'
                                : type == 'mp3' ||
                                        type == 'wma' ||
                                        type == 'mid' ||
                                        type == 'wav'
                                    ? 'lib/assets/mp3.png'
                                    : type == 'java'
                                        ? 'lib/assets/java.png'
                                        : type == 'rss'
                                            ? 'lib/assets/rss.png'
                                            : type == 'php'
                                                ? 'lib/assets/php.png'
                                                : type == 'xml'
                                                    ? 'lib/assets/xml.png'
                                                    : type == 'html'
                                                        ? 'lib/assets/html.png'
                                                        : type == 'css'
                                                            ? 'lib/assets/css.png'
                                                            : 'lib/assets/unknown.png';
    //set size
    String size;
    http.Response r = await http.head(url);
    final fileSize = int.parse(r.headers["content-length"]);
    if (fileSize >= 1024 && fileSize < 1048576) {
      size = '${(fileSize / 1024).toStringAsFixed(2)} KB';
    } else if (fileSize >= 1048576 && fileSize < 1073741824) {
      size = '${(fileSize / 1048576).toStringAsFixed(2)} MB';
    } else {
      size = '${(fileSize / 1073741824).toStringAsFixed(2)} G';
    }
    //set downloads directory path
    String path = await ExtStorage.getExternalStoragePublicDirectory(
        ExtStorage.DIRECTORY_DOWNLOADS);
    //start download
    final storagePermission = await Permission.storage.request();
    if (storagePermission.isGranted) {
      taskId = await FlutterDownloader.enqueue(
        url: url,
        savedDir: path,
        showNotification:
            true, // show download progress in status bar (for Android)
        openFileFromNotification:
            true, // click on notification to open downloaded file (for Android)
      );
    } else {
      return;
    }
    
    
    // trying a different way to get progress
    try {
      final tasks = await FlutterDownloader.loadTasksWithRawQuery(
          query: 'SELECT * FROM task WHERE status=3 AND progress<>0');
      final task = tasks.firstWhere((task) => task.taskId == taskId);
      int progress = task.progress;
      print(progress);
    } catch (e) {
      print(e);
    } // and it doesn't work
    
    
    _downloads.add(Download(
      name: name,
      size: size,
      status: 'Unknown',
      timeLeft: 'Unknown',
      transferRate: 'Unknown',
      type: type,
      path: path,
      icon: icon,
      progress: 5555,
    ));
    notifyListeners();
  }
}

这是我正在构建的照片 // StackOverFlow 不希望我上传照片

这是我的用户界面

@override
  Widget build(BuildContext context) {
    final downloadList = Provider.of<DownloadsProvider>(context).downloads;
    return GestureDetector(
      onTapDown: storePosition,
      onLongPress: () {
        setState(() {
          rowColor = Colors.blue;
        });
        showPopupMenu();
      },
      //showPopupMenu,
      child: Container(
        //height: 25,
        decoration: BoxDecoration(
          color: rowColor,
          border: Border(
            bottom: BorderSide(width: 1, color: Colors.grey[350]),
          ),
        ),
        child: Row(
          children: <Widget>[
            NameRowContainer(
              data: downloadList[widget.index].name,
              icon: downloadList[widget.index].icon,
            ),
            RowContainer(
                data: downloadList[widget.index].size,
                lastOne: false,
                width: 100),
            RowContainer(
              // I want to show progress here
                data: downloadList[widget.index].status,
                lastOne: false,
                width: 100),
            RowContainer(
                data: downloadList[widget.index].timeLeft,
                lastOne: false,
                width: 85),
            RowContainer(
                data: downloadList[widget.index].transferRate,
                lastOne: true,
                width: 120),
          ],
        ),
      ),
    );
  }

所以问题是我无法获得每个任务的进度并将其存储为下载中的进度变量 model soo 然后我可以在数据表中将其显示给用户,如上图所示,然后基于它创建一个线性进度指示器package 提供的方式来获得进展它适用于单个文件而不适用于所有文件,或者至少我无法解决它任何想法?

使用此回调:

static void downloadCallback(
      String id, DownloadTaskStatus status, int progress) {
    final SendPort send =
        IsolateNameServer.lookupPortByName('MyAppPrgrss' + id);
    send.send([id, status, progress]);
  }

这在你的 UI 部分:

void _bindBackgroundIsolate() {
    bool isSuccess = IsolateNameServer.registerPortWithName(
        _port.sendPort, port + _downloadTaskId);
    if (!isSuccess) {
      _unbindBackgroundIsolate();
      _bindBackgroundIsolate();
      return;
    }
    _port.listen((dynamic data) {
      String id = data[0];
      DownloadTaskStatus status = data[1];
      int progress = data[2];

      setState(() {
        if (id == _downloadTaskId) {
          this.progress = progress;

          if (status == DownloadTaskStatus.complete) {
            // TODO
          }
        }
      });
    });
  }

  void _unbindBackgroundIsolate() {
    IsolateNameServer.removePortNameMapping('MyAppPrgrss$_downloadTaskId');
  }

开始下载后注册回调并初始化taskID

   String _downloadTaskId = await FlutterDownloader.enqueue(
    url: downloadUrl,
    savedDir: path,
    fileName: fileName,
    showNotification: true,
    openFileFromNotification: true,
  );

FlutterDownloader.registerCallback(downloadCallback);

可以使用的方法之一是列出文件的 url:

List<String> downloadList= List<String>();
taskId = await FlutterDownloader.enqueue(
    url: url,
    savedDir: path,
    showNotification:
        true, // show download progress in status bar (for Android)
    openFileFromNotification:
        true, // click on notification to open downloaded file (for Android)
  ).then((fileUrl){
    downloadList.add(fileUrl);
  });

然后,在回调函数上遍历它们以获得它们各自的进度。

这个查询:

final tasks = await FlutterDownloader.loadTasksWithRawQuery(
      query: 'SELECT * FROM task WHERE status=3 AND progress<>0');

可能不是最好的解决方案,因为每次您想要检索进度值时都会有多个查询。 该资源不仅繁重,而且可能不准确。 回调应该是 go 的方式,因为它们以更好的方式获得相同的值,如此所述:

更新下载进度:FlutterDownloader.registerCallback(callback); //callback 是一个顶层或 static function

此外,这个repo有一个很好的例子,里面有很多关于相同回调的细节。

你可以使用flutter_downloader package。 package 在后台隔离执行其所有下载任务,从而提高性能并减少从头开始创建您的繁琐工作。 关于如何使用 package 的有用帖子: https://medium.com/@ezeaguprincewill5/flutter-downloader-package-implementation-made-easier-84b9153c1fbb

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM