[英]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.