flutter - flutter_downloader 获得许多任务的进度
问题描述
我正在使用 Flutter_downloader 包开发下载管理器应用程序,它是唯一为我们提供了很多选项的包,例如暂停、恢复、重试、取消、删除等等,但我面临的问题是进度问题。
我正在使用下载模型文件来定义下载
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),
],
),
),
);
}
所以问题是我无法获得每个任务的进度并将其存储为下载模型中的进度变量,然后我可以在数据表中将其显示给用户,如上图所示,然后基于它创建一个线性进度指示器软件包提供的获得进度的方式它适用于单个文件而不适用于所有文件,或者至少我无法解决任何想法?
解决方案
使用此回调:
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);
推荐阅读
- javascript - d3.js:分组条形图中的选择器下拉选择错误的图表
- javascript - 如何将标签的内部 html 更改为用户名?
- javascript - 将传统的 jQuery 链接平滑滚动方法转换为 vanilla javascript
- python - 如何在发送数据包之前对其进行编辑
- java - 我的简单列表集地图数据结构代码未编译,引发异常
- html - 如何在 CSS 中的父元素上应用“不显示”?
- javascript - 滚动时更改 React Element 的不透明度
- neovim - NeoVim 使终端窗口在程序退出时自动关闭
- java - java键盘功能适用于所有布局
- python - 数组之间所有成对除法的 Numpy 平均值