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

如何使用path_provider在iOS/Android外部存储写入字节文件

将PDF字节写入iOS/Android外部下载目录的解决方案

1. 依赖准备

在pubspec.yaml中添加所需包:

dependencies:
  path_provider: ^2.1.0
  permission_handler: ^10.2.0

执行flutter pub get完成依赖安装。

2. 平台权限配置

Android端

修改android/app/src/main/AndroidManifest.xml:

  • 添加权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  • 在<application>标签内添加适配分区存储的属性:
android:requestLegacyExternalStorage="true"

iOS端

修改ios/Runner/Info.plist,添加以下键值对确保文件能在系统"文件"APP中可见:

<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>

3. 完整实现代码

替换原有写入逻辑,使用以下异步方法:

import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

Future<void> savePdfToPublicDownloads(Solicitacao solicitacao) async {
  // 申请存储权限
  PermissionStatus permissionStatus;
  if (Platform.isAndroid) {
    permissionStatus = await Permission.manageExternalStorage.request();
    // 权限被拒时引导用户跳转到应用设置开启
    if (permissionStatus == PermissionStatus.denied) {
      await openAppSettings();
      return;
    }
  } else {
    permissionStatus = await Permission.storage.request();
    if (permissionStatus != PermissionStatus.granted) return;
  }

  // 获取系统下载目录
  Directory? downloadsDir;
  if (Platform.isAndroid) {
    // Android需拼接Downloads子目录
    final externalDir = await getExternalStorageDirectory();
    if (externalDir != null) {
      downloadsDir = Directory('${externalDir.path}/Download');
      await downloadsDir.create(recursive: true); // 目录不存在则创建
    }
  } else if (Platform.isIOS) {
    downloadsDir = await getDownloadsDirectory();
  }

  if (downloadsDir == null) return;

  // 写入PDF字节
  final targetFile = File('${downloadsDir.path}/${solicitacao.id}.pdf');
  await targetFile.writeAsBytes(solicitacao.matriculapdf);

  // 更新选中文件列表
  final existingIndex = selectedPdfs.indexWhere((file) => file.path == targetFile.path);
  if (existingIndex != -1) {
    selectedPdfs.removeAt(existingIndex);
  } else {
    selectedPdfs.add(targetFile);
  }
}

核心要点

  • Android 11+必须使用MANAGE_EXTERNAL_STORAGE权限,该权限无法通过弹窗直接授权,需引导用户到应用设置手动开启"所有文件访问权限"。
  • iOS的下载目录属于应用沙盒,但开启UIFileSharingEnabled后,用户可在"文件"APP的应用专属目录下找到生成的PDF。
  • 优先使用异步方法writeAsBytes避免阻塞UI线程,原代码中的同步方法writeAsBytesSync容易引发卡顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:38:35