行业知识
Flutter下载文件到本地
2026-11-07 12:42:09
来源:互联网转载
本示例中使用第三方库 flutter_downloader 使用Getx状态管理
在pubspec.yaml 引入插件
dependencies: flutter_downloader: ^1.11.6
在mian.dart中初始化插件
await FlutterDownloader.initialize( debug: true, // optional: set to false to disable printing logs to console (default: true) ignoreSsl: true // option: set to false to disable working with http links (default: false));
实际使用 文件详情controller
///声明接收端口final ReceivePort _port = ReceivePort();///下载状态bool isDown = false;///本地文件路径late String _saveLocalPath;///文件下载IDdynamic taskId = 0;///下载文档Future downloaderPdf() async { if (filePath.isEmpty) { print('文件地址为空'); return; } if (isDown) { print('正在下载,请勿重复点击'); return; } ///loading isDown = true; print('下载中...'); taskId = await FlutterDownloader.enqueue( url: filePath, ///文件地址 savedDir: _saveLocalPath, fileName: '测试文档', showNotification: false, ///在状态栏显示下载进度(仅限Android) openFileFromNotification: false, ///点击通知打开下载的文件 (仅限Android) ); ///合成本地路径 可以用来缓存 在下载记录中直接打开 localFilePath = '$_saveLocalPath/${fileDetails.filename}'; update();}///下载监听void _bindBackgroundIsolate() { final isSuccess = IsolateNameServer.registerPortWithName( _port.sendPort, 'downloader_send_port', ); if (!isSuccess) { _unbindBackgroundIsolate(); _bindBackgroundIsolate(); return; } _port.listen((dynamic data) async { ///重新下载状态 isDown = false; final taskId = (data as List)[0] as String; final status = data[1]; final progress = data[2] as int; if (status == 3) { print('下载完成'); ///打开文件 ///删除下载任务 await FlutterDownloader.remove( taskId: taskId, shouldDeleteContent: true, ); } ///其他status 自行处理 }); }///释放监听void _unbindBackgroundIsolate() { IsolateNameServer.removePortNameMapping('downloader_send_port');}///注册监听事件@pragma('vm:entry-point')static void downloadCallback( String id, int status, int progress,) { IsolateNameServer.lookupPortByName('downloader_send_port') ?.send([id, status, progress]);}@overridevoid onInit() { super.onInit(); WidgetsBinding.instance.addPostFrameCallback((_) async { _bindBackgroundIsolate(); FlutterDownloader.registerCallback(downloadCallback); ///获取文件存储路径 _saveLocalPath = await FileDirPath().prepareSaveDir(); update(); });}///页面关闭销毁监听@overrideonClose() { _unbindBackgroundIsolate(); super.onClose();} FileDirPath() 工具类 获取本地存储路径
导入对应插件
# 文件 path_provider: ^2.1.0 # 权限请求 permission_handler: ^11.0.0 # 设备信息 device_info_plus: ^9.1.1
import 'dart:io';import 'package:device_info_plus/device_info_plus.dart';import 'package:path_provider/path_provider.dart';import 'package:permission_handler/permission_handler.dart';class FileDirPath { late bool _permissionReady; Future retryRequestPermission() async { final hasGranted = await _checkPermission(); if (hasGranted) { await prepareSaveDir(); } _permissionReady = hasGranted; } ///获取文件保存路径 Future prepareSaveDir() async { String localPath = (await _getSavedDir())!; final savedDir = Directory(localPath); if (!savedDir.existsSync()) { await savedDir.create(); } return localPath; } Future _getSavedDir() async { String? externalStorageDirPath; final Directory? downloadsDir; if (Platform.isAndroid) { try { downloadsDir = await getDownloadsDirectory(); externalStorageDirPath = downloadsDir!.path; print('externalStorageDirPath: $externalStorageDirPath'); } catch (err, st) { print('failed to get downloads path: $err, $st'); final directory = await getExternalStorageDirectory(); externalStorageDirPath = directory?.path; } } else if (Platform.isIOS) { // var dir = (await _dirsOnIOS)[0]; // temporary // var dir = (await _dirsOnIOS)[1]; // applicationSupport // var dir = (await _dirsOnIOS)[2]; // library var dir = (await _dirsOnIOS)[3]; // applicationDocuments //var dir = (await _dirsOnIOS)[4]; // downloads dir ??= await getApplicationDocumentsDirectory(); externalStorageDirPath = dir.absolute.path; } return externalStorageDirPath; } Future get _dirsOnIOS async { final temporary = await getTemporaryDirectory(); final applicationSupport = await getApplicationSupportDirectory(); final library = await getLibraryDirectory(); final applicationDocuments = await getApplicationDocumentsDirectory(); final downloads = await getDownloadsDirectory(); final dirs = [ temporary, applicationSupport, library, applicationDocuments, downloads ]; return dirs; } Future _checkPermission() async { if (Platform.isIOS) { return true; } if (Platform.isAndroid) { final info = await DeviceInfoPlugin().androidInfo; if (info.version.sdkInt > 28) { return true; } final status = await Permission.storage.status; if (status == PermissionStatus.granted) { return true; } final result = await Permission.storage.request(); return result == PermissionStatus.granted; } throw StateError('unknown platform'); }} 总结
- flutter_downloader 集成配置参考插件官方文档
- **Android 存储权限变更 : **Android13以下需要声明存储权限,以上则不需要默认已授权
- 处理下载回调:flutter_downloader 插件提供了下载的回调函数,你可以利用这些回调来处理下载的状态变化,例如进度更新或下载完成。确保在你的应用中处理这些回调以提供更好的用户体验。
- 错误处理: 考虑在下载过程中处理可能的错误情况,例如网络不稳定、存储空间不足等。提供清晰的错误信息以便用户能够了解问题并可能采取相应的措施。
- 释放资源: 当你不再需要下载任务时,确保正确地释放资源,以避免潜在的内存泄漏
上一篇:acfun服务器怎么样?