使用前需要初始化
await FlutterDownloader.initialize(debug: debug);

import 'dart:isolate';
import 'dart:ui';
import 'dart:async';
import 'dart:io';import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:permission_handler/permission_handler.dart';const debug = true;class FlutterDownloaderDemo extends StatefulWidget with WidgetsBindingObserver {@override_FlutterDownloaderDemoState createState() => new _FlutterDownloaderDemoState();
}class _FlutterDownloaderDemoState extends State<FlutterDownloaderDemo> {final _documents = [{'name': 'Learning Android Studio','link': 'http://barbra-coco.dyndns.org/student/learning_android_studio.pdf'},{'name': 'Android Programming Cookbook','link': 'http://enos.itcollege.ee/~jpoial/allalaadimised/reading/Android-Programming-Cookbook.pdf'},{'name': 'iOS Programming Guide','link': 'http://darwinlogic.com/uploads/education/iOS_Programming_Guide.pdf'},{'name': 'Objective-C Programming (Pre-Course Workbook','link': 'https://www.bignerdranch.com/documents/objective-c-prereading-assignment.pdf'},];final _images = [{'name': 'Arches National Park','link': 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb.zol-img.com.cn%2Fsjbizhi%2Fimages%2F5%2F320x510%2F137760363184.jpg&refer=http%3A%2F%2Fb.zol-img.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1624849370&t=fb018c3ff3c939cf5dd5fb52210bec7d'},{'name': 'Canyonlands National Park','link': 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01251f57c36e000000012e7e27412c.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1624849370&t=609a5f51ecaa96b8e39b8747ea2fa2b2'},{'name': 'Death Valley National Park','link': 'https://upload.wikimedia.org/wikipedia/commons/b/b2/Sand_Dunes_in_Death_Valley_National_Park.jpg'},{'name': 'Gates of the Arctic National Park and Preserve','link': 'https://upload.wikimedia.org/wikipedia/commons/e/e4/GatesofArctic.jpg'}];final _videos = [{'name': 'Big Buck Bunny','link': 'http://commondatastorage.flutter-io.cn/gtv-videos-bucket/sample/BigBuckBunny.mp4'},{'name': 'Elephant Dream','link': 'http://commondatastorage.flutter-io.cn/gtv-videos-bucket/sample/ElephantsDream.mp4'}];//任务列表List<_TaskInfo> _tasks;//项目列表List<_ItemHolder> _items;//是否在加载bool _isLoading;//用户是否同意权限bool _permissionReady;//存储路径String _localPath;//接收端口ReceivePort _port = ReceivePort();@overridevoid initState() {super.initState();_bindBackgroundIsolate();//注册下载回调FlutterDownloader.registerCallback(downloadCallback);_isLoading = true;_permissionReady = false;//加载_prepare();}@overridevoid dispose() {_unbindBackgroundIsolate();super.dispose();}void _bindBackgroundIsolate() {bool isSuccess = IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');if (!isSuccess) {_unbindBackgroundIsolate();_bindBackgroundIsolate();return;}//注册接收端口监听_port.listen((dynamic data) {if (debug) {print('UI Isolate Callback: $data');}//任务idString id = data[0];//任务状态DownloadTaskStatus status = data[1];//任务进度int progress = data[2];if (_tasks != null && _tasks.isNotEmpty) {//查找对应的下载任务final task = _tasks.firstWhere((task) => task.taskId == id);if (task != null) {//更新下载任务状态和进度setState(() {task.status = status;task.progress = progress;});}}});}//释放资源void _unbindBackgroundIsolate() {IsolateNameServer.removePortNameMapping('downloader_send_port');}//下载回调static void downloadCallback(String id, DownloadTaskStatus status, int progress) {if (debug) {print('Background Isolate Callback: task ($id) is in status ($status) and process ($progress)');}final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');send.send([id, status, progress]);}@overrideWidget build(BuildContext context) {return new Scaffold(appBar: new AppBar(title: new Text('flutter_downloader文件下载'),),body: Builder(builder: (context) => _isLoading? new Center(child: new CircularProgressIndicator(),): _permissionReady? _buildDownloadList(): _buildNoPermissionWarning()),);}Widget _buildDownloadList() => Container(child: ListView(padding: const EdgeInsets.symmetric(vertical: 16.0),children: _items.map((item) => item.task == null? _buildListSection(item.name): DownloadItem(data: item,onItemClick: (task) {_openDownloadedFile(task).then((success) {if (!success) {Scaffold.of(context).showSnackBar(SnackBar(content: Text('Cannot open this file')));}});},onAtionClick: (task) {if (task.status == DownloadTaskStatus.undefined) {_requestDownload(task);} else if (task.status == DownloadTaskStatus.running) {_pauseDownload(task);} else if (task.status == DownloadTaskStatus.paused) {_resumeDownload(task);} else if (task.status == DownloadTaskStatus.complete) {_delete(task);} else if (task.status == DownloadTaskStatus.failed) {_retryDownload(task);}},)).toList(),),);Widget _buildListSection(String title) => Container(padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),child: Text(title,style: TextStyle(fontWeight: FontWeight.bold, color: Colors.blue, fontSize: 18.0),),);Widget _buildNoPermissionWarning() => Container(child: Center(child: Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.center,children: [Padding(padding: const EdgeInsets.symmetric(horizontal: 24.0),child: Text('Please grant accessing storage permission to continue -_-',textAlign: TextAlign.center,style: TextStyle(color: Colors.blueGrey, fontSize: 18.0),),),SizedBox(height: 32.0,),FlatButton(onPressed: () {_checkPermission().then((hasGranted) {setState(() {_permissionReady = hasGranted;});});},child: Text('Retry',style: TextStyle(color: Colors.blue,fontWeight: FontWeight.bold,fontSize: 20.0),))],),),);void _requestDownload(_TaskInfo task) async {task.taskId = await FlutterDownloader.enqueue(url: task.link,headers: {"auth": "test_for_sql_encoding"},savedDir: _localPath,showNotification: true,openFileFromNotification: true);}void _cancelDownload(_TaskInfo task) async {await FlutterDownloader.cancel(taskId: task.taskId);}void _pauseDownload(_TaskInfo task) async {await FlutterDownloader.pause(taskId: task.taskId);}void _resumeDownload(_TaskInfo task) async {String newTaskId = await FlutterDownloader.resume(taskId: task.taskId);task.taskId = newTaskId;}void _retryDownload(_TaskInfo task) async {String newTaskId = await FlutterDownloader.retry(taskId: task.taskId);task.taskId = newTaskId;}Future<bool> _openDownloadedFile(_TaskInfo task) {if (task != null) {return FlutterDownloader.open(taskId: task.taskId);} else {return Future.value(false);}}void _delete(_TaskInfo task) async {await FlutterDownloader.remove(taskId: task.taskId, shouldDeleteContent: true);await _prepare();setState(() {});}Future<bool> _checkPermission() async {if (Platform.isAndroid) {final status = await Permission.storage.status;if (status != PermissionStatus.granted) {final result = await Permission.storage.request();if (result == PermissionStatus.granted) {return true;}} else {return true;}} else {return true;}return false;}//加载任务、权限、下载项目等Future<Null> _prepare() async {//获取全部下载任务final tasks = await FlutterDownloader.loadTasks();int count = 0;_tasks = [];_items = [];//添加下载任务_tasks.addAll(_documents.map((document) => _TaskInfo(name: document['name'], link: document['link'])));_items.add(_ItemHolder(name: 'Documents'));for (int i = count; i < _tasks.length; i++) {_items.add(_ItemHolder(name: _tasks[i].name, task: _tasks[i]));count++;}//添加下载任务_tasks.addAll(_images.map((image) => _TaskInfo(name: image['name'], link: image['link'])));_items.add(_ItemHolder(name: 'Images'));for (int i = count; i < _tasks.length; i++) {_items.add(_ItemHolder(name: _tasks[i].name, task: _tasks[i]));count++;}//添加下载任务_tasks.addAll(_videos.map((video) => _TaskInfo(name: video['name'], link: video['link'])));_items.add(_ItemHolder(name: 'Videos'));for (int i = count; i < _tasks.length; i++) {_items.add(_ItemHolder(name: _tasks[i].name, task: _tasks[i]));count++;}tasks?.forEach((task) {for (_TaskInfo info in _tasks) {if (info.link == task.url) {info.taskId = task.taskId;info.status = task.status;info.progress = task.progress;}}});//权限是否就绪_permissionReady = await _checkPermission();_localPath = (await _findLocalPath()) + Platform.pathSeparator + 'Download';//savedDir下载文件存储位置final savedDir = Directory(_localPath);//判断目录是否存在bool hasExisted = await savedDir.exists();if (!hasExisted) {//创建目录savedDir.create();}setState(() {_isLoading = false;});}//获取存储目录地址Future<String> _findLocalPath() async {final directory = Platform.isAndroid//getExternalStorageDirectory,获取存储目录(android)? await (getExternalStorageDirectory() as FutureOr<Directory>)//获取存储目录: await getApplicationDocumentsDirectory();return directory.path;}
}
//下载项列表行
class DownloadItem extends StatelessWidget {final _ItemHolder data;final Function(_TaskInfo) onItemClick;final Function(_TaskInfo) onAtionClick;DownloadItem({this.data, this.onItemClick, this.onAtionClick});@overrideWidget build(BuildContext context) {return Container(padding: const EdgeInsets.only(left: 16.0, right: 8.0),child: InkWell(onTap: data.task.status == DownloadTaskStatus.complete? () {onItemClick(data.task);}: null,child: Stack(children: <Widget>[Container(width: double.infinity,height: 64.0,child: Row(crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[Expanded(child: Text(data.name,maxLines: 1,softWrap: true,overflow: TextOverflow.ellipsis,),),Padding(padding: const EdgeInsets.only(left: 8.0),child: _buildActionForTask(data.task),),],),),data.task.status == DownloadTaskStatus.running ||data.task.status == DownloadTaskStatus.paused? Positioned(left: 0.0,right: 0.0,bottom: 0.0,child: LinearProgressIndicator(value: data.task.progress / 100,),): Container()].where((child) => child != null).toList(),),),);}//构建任务行Widget _buildActionForTask(_TaskInfo task) {if (task.status == DownloadTaskStatus.undefined) {return RawMaterialButton(onPressed: () {onAtionClick(task);},child: Icon(Icons.file_download),shape: CircleBorder(),constraints: BoxConstraints(minHeight: 32.0, minWidth: 32.0),);} else if (task.status == DownloadTaskStatus.running) {return RawMaterialButton(onPressed: () {onAtionClick(task);},child: Icon(Icons.pause,color: Colors.red,),shape: CircleBorder(),constraints: BoxConstraints(minHeight: 32.0, minWidth: 32.0),);} else if (task.status == DownloadTaskStatus.paused) {return RawMaterialButton(onPressed: () {onAtionClick(task);},child: Icon(Icons.play_arrow,color: Colors.green,),shape: CircleBorder(),constraints: BoxConstraints(minHeight: 32.0, minWidth: 32.0),);} else if (task.status == DownloadTaskStatus.complete) {return Row(mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.end,children: [Text('Ready',style: TextStyle(color: Colors.green),),RawMaterialButton(onPressed: () {onAtionClick(task);},child: Icon(Icons.delete_forever,color: Colors.red,),shape: CircleBorder(),constraints: BoxConstraints(minHeight: 32.0, minWidth: 32.0),)],);} else if (task.status == DownloadTaskStatus.canceled) {return Text('Canceled', style: TextStyle(color: Colors.red));} else if (task.status == DownloadTaskStatus.failed) {return Row(mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.end,children: [Text('Failed', style: TextStyle(color: Colors.red)),RawMaterialButton(onPressed: () {onAtionClick(task);},child: Icon(Icons.refresh,color: Colors.green,),shape: CircleBorder(),constraints: BoxConstraints(minHeight: 32.0, minWidth: 32.0),)],);} else if (task.status == DownloadTaskStatus.enqueued) {return Text('Pending', style: TextStyle(color: Colors.orange));} else {return null;}}
}class _TaskInfo {final String name;final String link;String taskId;int progress = 0;DownloadTaskStatus status = DownloadTaskStatus.undefined;_TaskInfo({this.name, this.link});
}class _ItemHolder {final String name;final _TaskInfo task;_ItemHolder({this.name, this.task});
}

flutter_downloader文件下载插件相关推荐

  1. js下载图片、js下载文件、js文件下载插件介绍和使用方法 download.js

    知识点引用来自于 http://danml.com/download.html 在前端想要生成txt或者其他格式文件来保存一些数据,或者在数据请求服务器成功后想要将数据生成文件并下载,这些需求还是比较 ...

  2. 深度学习和机器博弈如何结合_对抗机器学习的博弈论方法

    深度学习和机器博弈如何结合 Artificial Intelligence has known a great success in recent years as it provided us wi ...

  3. IDEA插件:多线程文件下载插件开发

    摘要 上周使用Java开发了大文件多线程下载工具类,自己平时的文件下载也在使用这个工具,下载速度确实提升不少,但是每次下载都要去打开项目运行代码,觉得实在不是很方便:考虑到每天我们都会使用到IDEA开 ...

  4. 违禁词检索chrom扩展插件

    需求:本地违禁词库,匹配微信违禁词库. 思路: 1,先要在微信编辑页面进行植入js,对其进行操作:         2,上传本地本地违禁文件forbiddenword.txt:             ...

  5. firefox下的插件

    1.插件的安装 以下是一些特色插件,打开firefox后,从"工具"-->"附加组件"打开组件管理器,然后输入下面插件的关键词进行搜索安装即可,如下:打开 ...

  6. 【收藏】前端开发必备:前端开发不得不收藏的网站,提高200%开发效率!

    本项目为个人技术收藏集,里面会不定期分享一些作者平时用到的一些库,或者常用的网站和小工具.同时作者也会在上面不定期的写一些简单的博文 如果你有好的推荐你可以提 issue 或者 pr 来告诉作者 推荐 ...

  7. 前端js下载文件压缩包

    工作当中时常会遇到对文件的一些处理,比如下载表格.下载图片.下载文件等,这里说一种下载压缩包的方法. 其实也很简单,需要用到一款插件jszip,官方用法都是有的:https://www.npmjs.c ...

  8. 这里主要推荐一下前端常用,提高效率的一些库和软件

    ## 这里主要推荐一下自己平时常用,提高效率的一些库和软件 前端常用* sweetalert2 一个自适应,且自定义性强的弹出框(零依赖) tippy.js 最著名的 tooltip/popover ...

  9. 阅读分析程序源代码的一些方法(转载整理)

    前言 最近项目组中有较多新成员需要阅读熟悉项目中已有的程序代码,好多成员一时间对项目代码摸不清头绪,这里在网络上收集了相关源代码阅读分析的一些方法,整理于此. 正文 摘自(繁体中文Traditiona ...

最新文章

  1. makefille的使用
  2. 设计模式中遵循的原则:单一职责、开发-封闭、依赖倒转
  3. [ c++] cmake 编译时 undefined reference to `std::cout‘ 错误的解决方案
  4. WebService的事务处理 (转)
  5. Freemarker宏和函数的用法和区别
  6. 微商相册一直显示服务器偷懒,【小程序】微商个人相册多端小程序源码以及安装...
  7. Win7搭建http文件共享
  8. linux常用shell命令之文件操作命令
  9. 设为首页收藏本站js代码(引自ecshop模板堂(ecmoban.com)
  10. 吉他扒谱该怎么做?分享一款超好用的扒谱工具!
  11. Java怎样在饼状图上标注数字_饼状图 - java_jun - 博客园
  12. php exif信息,显示照片exif信息PHP代码
  13. 基于 HTML5 + WebGL 的太阳系 3D 可视化系统
  14. 【261期】为什么 BigDecimal 类不能使用 equals() 方法做等值比较?
  15. Andriod中如何新建lunch项
  16. iOS中WKWebView清除cookies
  17. 百万邮做邮件营销的邮箱配置
  18. Python获取下周一日期
  19. 吕 思 伟 ---- 潘 爱 民 :: ATL 介 绍( 一)
  20. android gpu平板 推荐,性能强的不像话,最强安卓平板华为平板M6上手

热门文章

  1. 洛谷P2245 星际导航(kruskal重构树)
  2. 什么是智能设备远程监控系统?
  3. 数据结构篇十七:图的最小生成树
  4. 协方差Cov(X,Y)的含义(转)
  5. 实战五十一:基于python机器学习深度学习实现股市评论情感分析 (完整代码+数据集可直接运行)
  6. 安装好RStudio打开提示 Error Starting R 问题怎么解决?
  7. Python量化交易开源框架:AmazingQuant
  8. 将时间戳转换为日期格式:moment、new Date()
  9. 自学成才的黑客(安全研究员)是从哪学到那些知识的?(跳转知乎)
  10. 正念,探寻自我觉醒之路(深度想考)