Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to write File download Manager based on Flutter in Android

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

这篇文章主要介绍"Android基于Flutter如何编写文件下载管理器",在日常操作中,相信很多人在Android基于Flutter如何编写文件下载管理器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Android基于Flutter如何编写文件下载管理器"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Dio 的下载方法 download

Dio 的下载方法定义如下:

Future download( String urlPath, savePath, { ProgressCallback? onReceiveProgress, Map? queryParameters, CancelToken? cancelToken, bool deleteOnError = true, String lengthHeader = Headers.contentLengthHeader, data, Options? options,});

urlPath:网络资源的 url;

savePath:dynamic 类型,可以是下载后存储文件路径的字符串,也可以是一个返回字符串的回调方法(Dio 会把 headers 参数携带过去,方便针对下载返回内容构建文件路径);

onReceiveProgress:文件接收进度,是一个void Function(int count, int total)回调函数,调用者可以通过该回调方法监测下载进度。

deleteOnError:发生错误时候是否删除已下载的文件,默认是 true。

lengthHeader:源文件的实际大小(未压缩前)。默认是 header 的content-length。如果文件压缩了,而没有指定该值的话,那进度回调里的total会是-1;如果使用自定义的 header 指定了文件的大小,那么total会是自定义的 header 对应的文件大小。

其他参数和普通的请求差不多,这里不再赘述。

为了不暴露下载的具体实现,我们在 http_util.dart 中封装一个自己的下载方法。

static Future download( String url, String savePath, { Map queryParams, CancelToken cancelToken, dynamic data, Options options, void Function(int, int) onReceiveProgress,}) async { try { return await _dioInstance.download( url, savePath, queryParameters: queryParams, cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); } on DioError catch (e) { if (CancelToken.isCancel(e)) { EasyLoading.showInfo('下载已取消!'); } else { if (e.response != null) { _handleErrorResponse(e.response); } else { EasyLoading.showError(e.message); } } } on Exception catch (e) { EasyLoading.showError(e.toString()); }}监测下载进度

我们新建一个文件下载页面 file_download.dart完成文件下载的示例。这里定义了几个属性来对文件下载过程进行反馈:

// 文件下载地址,这里是谷歌浏览器的下载地址(Mac 版本)String _downloadPath = 'https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg';// 下载进度比例,用于检测下载是否完成double _downloadRatio = 0.0;// 下载进度百分比String _downloadIndicator = '0.00%';// 下载文件的存储路径String _destPath;// 取消下载的 tokenCancelToken _token;// 指示当前是否处于下载中,以便做业务判断bool _downloading = false;

然后我们定义一个下载方法,在下载过程中如果 total 不为-1就更新下载进度,否则提示错误(实际调试发现,如果涉及到需要验证的,下载后后端实际会返回网页,这样也能下载网页内容下来,但是不是想要的文件)。

void _downloadFile() { _token = CancelToken(); _downloading = true; HttpUtil.download(_downloadPath, _destPath, cancelToken: _token, onReceiveProgress: (int received, int total) { if (total != -1) { if (!_token.isCancelled) { setState(() { _downloadRatio = (received / total); if (_downloadRatio == 1) { _downloading = false; } _downloadIndicator = (_downloadRatio * 100).toStringAsFixed(2) + '%'; }); } } else { _downloading = false; EasyLoading.showError('无法获取文件大小,下载失败!'); } });}

这里因为涉及到可能取消,因此只有在没有取消的情况下才更新下载状态,要不可能会出现取消的时候还处在下载接收字节的过程中,虽然取消了但是看到下载进度还在走的情况。

取消下载

取消下载其实很简单,当我们点击取消按钮的时候,调用 CancelToken 的cancel方法即可。这里我们做了一个判断,下载比例低于1才可以取消,因为下载完成再取消会抛出异常。同时取消后重置下载比例和显示的下载百分比。

void _cancelDownload() { if (_downloadRatio

< 1.0) { _token.cancel(); _downloading = false; setState(() { _downloadRatio = 0; _downloadIndicator = '0.00%'; }); }}删除已经下载的文件 对于 App,没有别的入口管理文件,因此实际过程中我们需要提供下载入口供用户清理已下载的文件。实际已下载的文件,我们需要有下载文件管理功能供用户管理文件,这个时候会需要本地存储支撑,我们在后续的章节会介绍本地存储。 删除文件前需要判断文件是否存在,如果文件不存在删除可能抛出异常。文件的管理使用的是 dart:io 中的方法。 void _deleteFile() { try { File downloadedFile = File(_destPath); if (downloadedFile.existsSync()) { downloadedFile.delete(); } else { EasyLoading.showError('文件不存在'); } } catch (e) { EasyLoading.showError(e.toString()); }} path_provider文件目录管理 在 App 中没法直接知道应用的文件存储目录,因此需要借用 path_provider 插件来获取 App 的文件存储目录,path_provider 提供了如下方法: getTemporaryDirectory:应用临时目录(可能被清除) getApplicationDocumentsDirectory:应用文档目录(不会被系统清除,主要用户数据存储目录),对于安卓推荐使用外部存储getExternalStorageDirectory。 getApplicationSupportDirectory:应用支持目录,一般放置与用户无关的数据。 getLibraryDirectory:指向应用可以持久存储数据的目录,不支持安卓平台。 getExternalStorageDirectory:获取外部存储目录,不支持 iOS 平台。 getExternalCacheDirectories:获取外部缓存目录,,不支持 iOS 平台。 getExternalStorageDirectories:获取外部可以的目录列表,不支持 iOS 平台。 getDownloadsDirectory:获取下载目录,用于 Web 端,不支持安卓和 iOS平台。 通过 path_provider拿到Directory对象后,就可以通过 Directory的 path 属性获取到完整的目录路径。本例我们是在 initialState 里获取文件存储路径的,使用的是临时目录。 void initState() { getTemporaryDirectory() .then((tempDir) =>

{_destPath = tempDir.path +'googlechrome.dmg'}); super.initState();} Some errors encountered during debugging

OS Error: Read-only file system: Android requires READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. At the same time, you need to use path_provider to obtain the file directory of the application, and then read and write files and access the file directory to the corresponding directory.

If total=-1 in onReceivedProgress, it means that the file is compressed or session information is required before it can be downloaded (e.g., authentication is enabled on the backend).

When deleting a file, check whether the file is in the process of downloading. If deleting the file in the process of downloading will cause a file read-write conflict, an exception will be thrown.

CancelToken instance can only cancel a request once, so you need to rebuild CancelToken object every time you make a request, otherwise you can't cancel it again after canceling it once.

Run results and code

The operation results are shown in the following figure:

At this point, the study of "Android based on Flutter how to write a file download manager" is over, hoping to solve everyone's doubts. Theory and practice can better match to help everyone learn, go and try it! If you want to continue learning more relevant knowledge, please continue to pay attention to the website, Xiaobian will continue to strive to bring more practical articles for everyone!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report