Android 11(SDK30)运行时创建Android/data目录失败,mkdirs返回false报文件未找到
Android 11 环境下运行时创建目录失败的核心原因
根本触发规则
Android 11(API 30)正式落地强制分区存储(Scoped Storage)机制,对应用访问外部存储的权限边界做了严格收紧,你碰到的mkdirs()始终返回false、抛出文件未找到异常,本质是权限拦截导致的路径访问失败,具体原因如下:
- 硬编码路径无访问权限:你代码中直接拼接的
/storage/emulated/0/Android/data/myproject.data属于应用私有外部存储目录,虽然这个目录归属你的应用所有,但分区存储机制下,所有对/Android/data/路径的直接硬编码File操作都会被系统拦截,不会给应用开放该路径的直接读写权限,哪怕是自己包名对应的子目录也不例外。 - 目录层级不符合开放要求:你尝试在
/Android/data/你的包名/根目录下直接创建自定义的logcat子文件夹,本身不在系统开放的可操作目录范围内,该层级的路径只有系统有写入权限,应用无法直接在根目录下新建自定义文件夹,系统预先创建的files、cache等子目录,才是通过官方API开放可操作的路径。 - 父目录校验失败导致
mkdirs()失效:File.mkdirs()需要先逐级校验所有父目录的可访问性,当系统拦截了你对目标路径的访问请求时,会直接返回该路径不存在的判定,此时没有创建子目录的前置条件,mkdirs()自然会返回false,触发else分支。 - 部分设备存在存储路径映射差异:硬编码的
/storage/emulated/0/路径并非全设备通用,部分定制ROM会将外部存储挂载点映射到其他路径,直接使用硬编码路径会在系统层抛出文件未找到的底层异常,和你观察到的现象完全匹配。
正确实现方式
不需要手动拼接硬编码存储路径,直接调用系统提供的上下文API获取可访问的应用专属目录即可,整个过程不需要申请任何存储权限:
示例代码:
// 获取应用专属外部存储根目录,系统会自动处理路径映射和权限开放 // 返回路径对应 /storage/emulated/0/Android/data/你的包名/files File appExternalRoot = getApplicationContext().getExternalFilesDir(null); // 在根目录下拼接需要的logcat子目录 File logDirectory = new File(appExternalRoot, "logcat"); if (!logDirectory.exists()) { boolean isCreated = logDirectory.mkdirs(); // 正常场景下isCreated会返回true,不会进入失败分支 }
补充注意事项
- 不要尝试通过申请
MANAGE_EXTERNAL_STORAGE全文件访问权限去读写Android/data目录,Android 13及以上版本已经收紧了该权限对Android/data、Android/obb路径的访问限制,即便有权限也无法通过File API直接操作这些路径。 - 应用专属外部存储目录下创建的文件,会在应用卸载时被系统自动清除,不需要额外做清理逻辑。
内容的提问来源于stack exchange,提问作者TraderAndroid
相关产品推荐
相关产品推荐

