Flutter中flutter_downloader下载成功却提示失败的问题求助
解决FlutterDownloader下载成功但通知显示失败的问题
问题核心原因
从错误日志可以明确,FileProvider未配置Download目录的访问路径,导致下载完成后生成文件Uri时失败,进而触发通知显示"failed to download"——尽管文件实际已经成功保存到Downloads文件夹。
解决方案步骤
1. 配置FileProvider路径文件
在res/xml目录下创建paths.xml文件(若没有xml目录则新建),添加Download目录的映射规则:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 映射外部存储的Download目录 --> <external-path name="external_download" path="Download"/> </paths>
2. 更新AndroidManifest.xml
添加FileProvider的声明,确保它能访问Download目录。将以下代码添加到<application>标签内:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/paths"/> </provider>
注意:
android:authorities的值要和后续Dart代码中指定的fileProviderAuthority保持一致。
3. 优化Dart代码
- 替换硬编码的存储路径,使用
path_provider获取标准的Download目录 - 适配Android 13+的权限要求
- 指定
fileProviderAuthority参数给FlutterDownloader
首先确保pubspec.yaml添加依赖:
dependencies: flutter_downloader: ^latest_version path_provider: ^latest_version package_info_plus: ^latest_version permission_handler: ^latest_version
修改下载函数:
import 'dart:io'; import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:path_provider/path_provider.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:permission_handler/permission_handler.dart'; void _download(String url) async { // 权限处理 if (Platform.isAndroid) { if (await Permission.storage.isDenied) { await Permission.storage.request(); } // Android 13+ 需额外请求音频读取权限 if ((await DeviceInfoPlugin().androidInfo).version.sdkInt >= 33) { await Permission.audio.request(); } } // 获取公共Download目录路径 final downloadDir = await getExternalStoragePublicDirectory(DirectoryDownloads); final savedDir = downloadDir.path; // 获取App包名,用于FileProvider的authorities final packageInfo = await PackageInfo.fromPackageInfo(); final fileProviderAuthority = "${packageInfo.packageName}.fileprovider"; final id = await FlutterDownloader.enqueue( fileName: "LRMonoPhase4.mp3", url: 'https://www.kozco.com/tech/LRMonoPhase4.mp3', savedDir: savedDir, showNotification: true, openFileFromNotification: true, fileProviderAuthority: fileProviderAuthority, ); util.showToast(id.toString()); }
4. 清理重建项目
执行以下命令确保配置生效:
flutter clean flutter pub get flutter run
关键说明
- 硬编码
/storage/emulated/0/Download路径在部分设备上可能存在兼容性问题,使用path_provider的API能保证路径正确性 - FileProvider是Android系统用于安全分享文件的机制,FlutterDownloader在打开通知中的文件时必须依赖它生成合法的Content Uri
- Android 13+对媒体权限做了细分,针对音频文件需要申请
Permission.audio才能正常打开
内容的提问来源于stack exchange,提问作者Anandh Krishnan
相关产品推荐
相关产品推荐

