You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11+下Flutter用dio下载PDF至Downloads文件夹并操作的方法

Dio下载PDF到Downloads文件夹的权限与操作解决方案

解决重复文档树弹窗问题

你用shared_storage时PersistedUris失效,大概率是没走对持久化流程:

  • 第一次调用openDocumentTree时,必须让用户选中整个Downloads目录(别选子文件夹),这是获取持久化权限的前提
  • 选中后立刻调用persistUriPermission把Uri存下来,之后每次启动App用getPersistedUriPermissions取已授权的Uri,就不用再弹文档树了
  • 代码示例:
// 首次授权流程
final Uri? downloadsUri = await openDocumentTree(initialUri: downloadsDirectoryUri);
if (downloadsUri != null) {
  await persistUriPermission(downloadsUri);
}

// 后续直接用持久化的Uri
final persistedUris = await getPersistedUriPermissions();
if (persistedUris.isNotEmpty) {
  final targetUri = persistedUris.first;
  // 用这个Uri操作Downloads下的文件/文件夹
}

无需用户手动创建子文件夹:直接写入Downloads

Android允许应用直接往Downloads目录写文件,不用用户手动创建以应用命名的子文件夹,结合Dio的实现步骤:

  1. 先用Dio把PDF下载到App的临时目录
  2. 通过MediaStore把文件复制到Downloads目录,同时拿到可用于后续操作的ContentUri
  3. 后续查看、删除都用这个ContentUri即可
  • 代码示例:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:shared_storage/shared_storage.dart';
import 'package:path_provider/path_provider.dart';

Future<void> downloadAndSaveToDownloads(String pdfUrl, String fileName) async {
  // 1. 下载到临时目录
  final tempDir = await getTemporaryDirectory();
  final tempFile = File('${tempDir.path}/$fileName');
  await Dio().download(pdfUrl, tempFile.path);

  // 2. 写入Downloads目录
  final contentUri = await insertMedia(
    DownloadsCollection.uri,
    {
      DownloadsCollection.displayName: fileName,
      DownloadsCollection.mimeType: 'application/pdf',
      DownloadsCollection.isPending: false,
    },
    sourceFile: tempFile,
  );

  // 3. 后续操作示例:删除文件
  await deleteMedia(contentUri);
  // 查看可通过contentUri调用系统文件查看器
}

替代插件与方案

如果shared_storage不好用,可以换这些思路:

  • 试试media_store插件:专门针对MediaStore操作,不用SAF就能往Downloads写文件,权限处理更简洁
  • 自定义原生工具类:直接调用Android的SAF API处理持久化权限,避开插件封装的坑

关键注意事项

  • Android 13+中,应用访问自己写入Downloads的文件无需额外权限;针对Android 12及以下,需在AndroidManifest.xml中申请READ_EXTERNAL_STORAGE权限
  • 若必须创建应用名子文件夹,首次拿到Downloads的持久化Uri后,用createDirectory方法在其下创建子文件夹,后续直接操作该子文件夹的Uri即可

内容的提问来源于stack exchange,提问作者LordShrunkenant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:33:13