Flutter中使用Dio下载文件时Android作用域存储(Scope Storage)是否存在权限漏洞?
为什么Dio无需权限就能在Android 11的Downloads目录写入文件?
这其实不是作用域存储(Scope Storage)的漏洞,而是Android针对公共媒体目录的权限规则和Dio底层实现的结合效果,我来给你详细解释:
1. Android 11对公共目录的权限设计
- 作用域存储的核心限制是禁止APP随意访问其他APP创建的文件,以及限制对非公共目录的无差别读写,但对于系统预设的公共媒体目录(比如Downloads、Pictures、Movies等),Android有特殊规则:
- APP不需要申请
READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限,就可以在这些目录下创建、写入属于自己的新文件。 - 这里的关键是“自己的文件”——系统会默认赋予创建该文件的APP对它的所有权,后续APP也能正常读写这个文件,但无法随意访问其他APP在公共目录下的文件。
- APP不需要申请
2. Dio的底层实现刚好适配了这个规则
你提到的Dio源码里的这段逻辑:
file.createSync(recursive: true); var raf = file.openSync(mode: FileMode.write);
在Android端最终会映射到原生的java.io.File相关API:
file.createSync()对应原生的File.createNewFile()或mkdirs(),负责在Downloads目录下创建新的文件/目录,这个操作因为是向公共目录添加自有内容,被Android权限机制放行。RandomAccessFile.openSync()则是基于已创建的文件句柄进行写入,因为APP已经拥有该文件的所有权,所以不需要额外权限就能完成写入操作。
3. flutter_downloader的问题根源
flutter_downloader目前不支持作用域存储,大概率是因为它的实现依赖了旧的下载逻辑:
- 比如它可能调用了系统下载管理器的某些旧API,或者尝试直接操作已存在的文件(而非创建新文件),这些场景会触发作用域存储的限制,导致需要额外权限或直接失败。
总结
这完全是符合Android 11权限规范的正常行为,并非漏洞。作用域存储的设计目标是保护用户数据隐私,同时又不会完全限制APP向公共目录贡献内容——Dio的实现刚好踩中了这个被允许的场景,而flutter_downloader的旧实现没有适配这个规则。
内容的提问来源于stack exchange,提问作者Huy Nguyen
相关产品推荐
相关产品推荐

