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

Flutter在Android11/12中无法将Excel文件保存至下载文件夹问题

Flutter 应用在 Android 11+ 无法保存文件到下载目录的解决方案

问题原因

Android 11(API 30)及以上版本启用了Scoped Storage(分区存储)机制,禁止应用直接通过绝对路径(如/storage/emulated/0/Download/)访问公共存储目录,这就是触发Operation not permitted, errno=1错误的核心原因。Android 11以下版本无此限制,所以能正常保存文件。

解决方法

方法1:使用MediaStore API保存(推荐,符合官方规范)

这是Android 11+官方推荐的公共存储文件操作方式,无需申请特殊权限,且能通过谷歌商店审核。

Flutter实现示例(借助第三方插件)

使用media_store插件简化操作:

import 'package:media_store/media_store.dart';
import 'dart:typed_data';

Future<bool> saveCsvToDownload(Uint8List csvBytes, String fileName) async {
  final mediaStore = MediaStore();
  // 保存到Download/myExcel目录下
  final saveUri = await mediaStore.saveFile(
    path: MediaStore.downloadsDirectory,
    fileName: fileName,
    bytes: csvBytes,
    mimeType: 'text/csv',
    subDir: 'myExcel', // 指定子目录
  );
  return saveUri != null;
}

原生Android实现(自定义MethodChannel)

如果不想依赖第三方插件,可自行编写原生代码:

// Android端Kotlin代码
fun saveCsvToDownload(context: Context, fileName: String, csvBytes: ByteArray): Boolean {
    val contentValues = ContentValues().apply {
        put(MediaStore.Downloads.DISPLAY_NAME, fileName)
        put(MediaStore.Downloads.MIME_TYPE, "text/csv")
        // 指定下载目录下的子文件夹
        put(MediaStore.Downloads.RELATIVE_PATH, "${Environment.DIRECTORY_DOWNLOADS}/myExcel")
    }

    context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)?.let { uri ->
        context.contentResolver.openOutputStream(uri)?.use { outputStream ->
            outputStream.write(csvBytes)
            return true
        }
    }
    return false
}

方法2:申请MANAGE_EXTERNAL_STORAGE权限(谨慎使用)

此权限为特殊权限,仅适用于文件管理器、备份类等需要全局存储访问的应用,普通应用使用可能被谷歌商店拒绝上架。

  1. 在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  1. Flutter端请求权限(需permission_handler插件):
import 'package:permission_handler/permission_handler.dart';

Future<void> requestStoragePermission() async {
  if (!await Permission.manageExternalStorage.isGranted) {
    // 引导用户到系统设置开启权限
    await openAppSettings();
  }
}

权限授予后,即可继续使用原有的绝对路径方式保存文件。

权限适配补充

为兼容低版本Android,在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:07:33