FlutterDownloader下载文件失败求助(仅Android 10设备出现)
解决Android 10设备FlutterDownloader下载PDF启动即失败的问题
可能原因及修复方案
1. 适配Android 10的Scoped Storage
Android 10(API 29)启用了Scoped Storage,传统的外部存储直接访问路径会被限制:
- 放弃
Environment.getExternalStorageDirectory()这类旧路径,改用应用专属存储目录,比如通过path_provider包的getExternalStorageDirectory()(Android10+下指向应用专属目录)或getApplicationDocumentsDirectory()获取路径。 - 若必须使用公共目录,可在
AndroidManifest.xml中添加android:requestLegacyExternalStorage="true"做临时兼容,但长期建议适配Scoped Storage规范。
2. 确保存储权限正常
- 在
AndroidManifest.xml中声明权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> - 下载前动态申请权限,可借助
permission_handler包实现:先检查权限状态,未授权则发起请求,拒绝权限时需做对应提示处理。
3. 验证下载路径有效性
- 确认
_path对应的目录存在,不存在则提前创建:final dir = Directory(_path); if (!await dir.exists()) { await dir.create(recursive: true); } - 避免路径或文件名包含特殊字符,确保
_fileName格式合法。
4. 检查FlutterDownloader配置
- 确保Android端
AndroidManifest.xml已注册下载服务:<service android:name="vn.hunghd.flutterdownloader.DownloadService" android:exported="false"> <intent-filter> <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> </intent-filter> </service> - 更新FlutterDownloader到最新稳定版,旧版本可能存在Android10适配缺陷。
5. 测试下载URL可用性
直接在浏览器或其他工具中测试目标URL,确认能正常下载PDF,排除服务器端或URL本身的问题。
修正后示例代码
import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; // 存储权限检查 Future<bool> checkStoragePermission() async { var status = await Permission.storage.status; if (!status.isGranted) { status = await Permission.storage.request(); } return status.isGranted; } // 获取合法下载路径 Future<String> getValidDownloadPath() async { final appDir = await getExternalStorageDirectory(); final downloadDir = '${appDir!.path}/PDFDownloads'; final dir = Directory(downloadDir); if (!await dir.exists()) { await dir.create(recursive: true); } return downloadDir; } // 执行下载 Future<void> startPdfDownload(String url, String fileName) async { final hasPermission = await checkStoragePermission(); if (!hasPermission) { // 处理权限拒绝逻辑,比如弹窗提示 return; } final savePath = await getValidDownloadPath(); await FlutterDownloader.enqueue( url: Uri.parse(url).toString(), savedDir: savePath, fileName: fileName, showNotification: true, openFileFromNotification: true, ); }
内容的提问来源于stack exchange,提问作者Nandhini Ravichandran
相关产品推荐
相关产品推荐

