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

Flutter读写Android/data文件夹权限报错(errno=3)求助

问题分析与解决方案

你的需求在部分Android版本下可实现,但受限于Android 10+引入的Scoped Storage机制,直接访问其他应用的Android/data目录存在系统级限制,你遇到的权限拒绝(errno=3)正是这个原因导致的,权限处理上存在以下疏漏:

核心限制说明

从Android 10(API 29)开始,系统引入Scoped Storage,Android/data属于其他应用的专属私有目录,默认禁止第三方应用直接读写。哪怕你申请了READ_EXTERNAL_STORAGE或MANAGE_EXTERNAL_STORAGE权限,在Android 11+系统中,也无法直接通过File API访问该目录下的文件。

权限处理的疏漏

  1. MANAGE_EXTERNAL_STORAGE是特殊权限:这个权限不能通过普通的权限申请流程获取,必须引导用户手动进入系统设置的「应用特殊权限」页面开启,代码里的权限申请弹窗不会触发该权限的授权。
  2. 权限不覆盖所有场景:即便用户开启了MANAGE_EXTERNAL_STORAGE,Android 11+依然限制第三方应用直接访问其他应用的Android/data和Android/obb目录,这是系统硬规则,无法通过权限绕过。

可行实现方案

导出功能

  • 使用存储访问框架(SAF):通过Intent唤起系统文件选择器,让用户手动找到游戏存档文件(需用户知晓存档在Android/data/[游戏包名]下的具体路径),获取文件的Uri后,通过ContentResolver将文件复制到下载目录。
  • 兼容Android 9及以下:这部分系统无Scoped Storage限制,可直接用File API完成复制操作。

导入功能

  • 同样依赖SAF:让用户选择要导入的存档文件,再通过SAF尝试写入游戏的Android/data目录。但注意:Android 11+下,除非游戏应用通过ContentProvider开放了写入权限,否则你无法直接写入其专属目录,此时只能引导用户手动复制文件,或使用root权限(但root不具备通用性)。

关键代码提示

以SAF获取文件为例:

// 唤起文件选择器
final intent = Intent(
  action: IntentConstants.ACTION_OPEN_DOCUMENT,
  type: '*/*',
);
await intent.launch();
// 获取返回的Uri
final uri = intent.resultData;
// 通过ContentResolver读取文件
final inputStream = await contentResolver.openInputStream(Uri.parse(uri));
// 写入到下载目录
final outputFile = File('${(await getExternalStorageDirectory())?.path}/Download/存档文件');
await inputStream?.pipe(outputFile.openWrite());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:56:15