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

如何修复Flutter的FileSystemException文件无法打开权限拒绝错误

问题描述

我用Dart和dart_git包开发读取Git仓库数据的Flutter应用,读取.git/config文件时触发权限错误:

I/flutter (13909): Error: FileSystemException: Cannot open file, path = '/storage/emulated/0/Download/git_repository/.git/config' (OS Error: Permission denied, errno = 13)

已在AndroidManifest.xml添加权限:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
     android:requestLegacyExternalStorage="true"

试过真机和不同模拟器,但问题依旧。


解决方案

1. 修复MANAGE_EXTERNAL_STORAGE权限请求逻辑

Android 11+中,MANAGE_EXTERNAL_STORAGE是特殊权限,无法通过普通弹窗请求获取,必须引导用户到应用设置页手动开启:

Future<bool> _requestManageStoragePermission() async {
  if (!await Permission.manageExternalStorage.isGranted) {
    // 跳转到应用设置页让用户手动开启权限
    await openAppSettings();
    return await Permission.manageExternalStorage.isGranted;
  }
  return true;
}

替换你代码中_hasFileAccessPermission和_requestFileAccessPermission里的权限请求逻辑,确保先检查权限状态,未授权时直接跳转设置页。

2. 调整权限请求时机

不要等到加载Git仓库后才检查权限,应该在选择文件夹前完成所有必要权限的验证:

onPressed: () async {
  // 先处理Android 11+的特殊存储权限
  bool hasManagePerm = await _requestManageStoragePermission();
  if (!hasManagePerm) {
    print("需要授予「管理所有文件」权限才能访问仓库");
    return;
  }
  
  // 兼容低版本的常规存储权限
  PermissionStatus storageStatus = await Permission.storage.request();
  if (storageStatus.isGranted) {
    String? directoryPath = await FilePicker.platform.getDirectoryPath();
    if (directoryPath != null) {
      setState(() {
        _selectedPath = directoryPath;
      });
      await _initializeGitRepo(Directory(directoryPath));
    }
  } else {
    print('存储权限未授予');
  }
},

3. 完善AndroidManifest配置

针对不同Android版本拆分权限配置,确保requestLegacyExternalStorage仅作用于Android 10(API 29),同时补全application标签的闭合:

<!-- Android 11+ 需单独声明管理存储权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    android:minSdkVersion="30"/>
<!-- Android 10及以下用读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
    android:requestLegacyExternalStorage="true"
    <!-- 其他原有配置 -->
    >
    <!-- 活动等组件配置 -->
</application>

4. 调整仓库加载顺序

你的代码中先执行GitRepository.load再检查权限,会直接触发权限错误。修改_initializeGitRepo,确保权限验证通过后再加载仓库:

Future<void> _initializeGitRepo(Directory directory) async {
  try {
    // 先确认权限已授予,再加载仓库
    bool hasPerm = await Permission.manageExternalStorage.isGranted && await Permission.storage.isGranted;
    if (!hasPerm) {
      print("权限不足,无法访问仓库");
      return;
    }

    GitRepository gitRepo = await GitRepository.load(directory.path);
    // 后续读取HEAD、提交信息的逻辑...
  } catch (e) {
    print('Error: $e');
  }
}

5. 测试注意事项

  • Android 11+设备必须手动到「应用设置」-「权限」-「存储」中开启「允许管理所有文件」,仅弹窗请求无法获取该权限。
  • 测试前卸载旧版本应用,避免权限缓存导致的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:02:04