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

Flutter创建外部存储文件夹报Operation not permitted权限错误

问题原因

报错核心是Android高版本存储权限规则变更:

  • Android 10(API 29)开始强制启用分区存储,普通应用默认只能访问自己的专属存储目录和授权的公共媒体目录
  • Android 11(API 30)及以上版本完全废弃了WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE的根目录读写能力,仅靠这两个权限根本无法直接在storage/emulated/0/根目录创建文件/文件夹

另外你的代码本身还有三个逻辑缺陷:

  • 调用权限申请方法后没有二次校验授权结果,用户拒绝权限后代码还是会继续执行创建文件夹的逻辑
  • 硬编码存储根目录路径,不同厂商、不同系统版本的外部存储路径不一定是storage/emulated/0/
  • 调用path.create()时没加recursive: true参数,只要上级目录不存在就会直接抛创建失败的错误
修复方案

1. 修改AndroidManifest.xml配置

在原有权限声明下补充高版本需要的权限,同时给application标签添加Android 10兼容属性:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cameraapp">
    <!-- 原有权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!-- 新增Android11+需要的所有文件访问权限 -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

   <application
        android:label="cameraapp"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        <!-- 新增这行,兼容Android10分区存储过渡规则 -->
        android:requestLegacyExternalStorage="true">
        <!-- 其余activity等配置保持原样即可 -->
    </application>
</manifest>

2. 修正Dart层逻辑

不要硬编码路径,按系统版本分支申请对应权限,申请后必须校验结果再执行文件操作,修正后的代码如下:

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

Future<String> createTargetFolder() async {
  const folderName = "newcreatefoldr";
  
  if (Platform.isAndroid) {
    PermissionStatus storageStatus;
    // Android11及以上版本申请管理所有文件权限
    if (int.parse(Platform.version.split('.')[0]) >= 11) {
      storageStatus = await Permission.manageExternalStorage.status;
      if (!storageStatus.isGranted) {
        storageStatus = await Permission.manageExternalStorage.request();
      }
    } else {
      // Android10及以下用旧存储权限
      storageStatus = await Permission.storage.status;
      if (!storageStatus.isGranted) {
        storageStatus = await Permission.storage.request();
      }
    }
    // 权限未授予直接终止流程
    if (!storageStatus.isGranted) {
      throw FileSystemException("存储权限未授予,无法创建文件夹");
    }
  }

  // 通过官方插件获取外部存储路径,不要硬编码
  final Directory? externalRoot = await getExternalStorageDirectory();
  if (externalRoot == null) {
    throw FileSystemException("无法获取设备外部存储路径");
  }
  final Directory targetDir = Directory("${externalRoot.path}/$folderName");
  
  if (!await targetDir.exists()) {
    // recursive设为true会自动创建缺失的上级目录
    await targetDir.create(recursive: true);
  }
  return targetDir.path;
}

3. 额外说明

  • 如果你的应用不需要在存储根目录创建文件夹,只是存应用自己的文件,完全可以不用申请任何存储权限,直接调用getApplicationDocumentsDirectory()或者getExternalStorageDirectory()拿到应用专属目录操作即可,不会有权限问题
  • 若需要上架Google Play,使用MANAGE_EXTERNAL_STORAGE权限必须在审核时明确说明使用场景,仅当应用是文件管理器、备份工具这类确实需要访问全存储的场景才能通过审核,普通应用用这个权限会被直接拒审

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:30:44