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

已申请WRITE_EXTERNAL_STORAGE权限但mkdirs()返回false的排查方法

排查Android中mkdirs()创建目录失败的具体方法

针对你遇到的mkdirs()返回false、无法创建备份目录的问题,可从以下几个维度逐一排查:

1. 适配Android 10+的Scoped Storage机制

Android 10(API 29)及以上版本引入了分区存储(Scoped Storage),直接通过Environment.getExternalStorageDirectory()在外部存储根目录创建自定义目录会被系统限制,即使申请了WRITE_EXTERNAL_STORAGE权限也无法生效。

解决方式:

  • 使用应用专属外部存储目录:通过Context.getExternalFilesDir(String type)获取,该目录属于应用私有空间,无需额外权限(Android 10+),卸载应用时会被自动删除:
    // 替换原有的backupFolder创建逻辑
    File backupFolder = new File(getExternalFilesDir(null), BACKUP_FOLDER_NAME);
    
  • 如果需要将备份文件放在公共目录(如Download),需使用MediaStore API或MANAGE_EXTERNAL_STORAGE权限(仅适用于特殊场景,不推荐普通应用使用)。

2. 补全权限请求的回调逻辑

你的代码中请求权限后直接调用finish(),没有处理权限授予后的后续操作。当用户授予权限时,Activity已销毁,不会执行createBackup()。需重写权限回调方法:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            try {
                createBackup();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("Backup", e.getMessage());
            }
        }
        finish();
    }
}

3. 修复代码中的冗余与错误逻辑

  • 你在mkdirs()成功后重复调用了一次backupFolder.mkdirs(),由于目录已存在,第二次调用会返回false,导致日志显示Geslaagdfalse,属于无效操作,直接删除重复调用即可。
  • 异常处理部分无需在mkdirs()失败后捕获自己抛出的IOException,直接向上抛出或简化处理:
    if (!backupFolder.mkdirs()) {
        Log.e("Backup", "Gefaald: " + backupFolder.getAbsolutePath());
        throw new IOException("Dir maken gefaald");
    }
    

4. 打印更详细的调试信息

通过以下方式获取更多失败细节:

  • 打印目录的规范路径:Log.d("Backup", "Canonical path: " + backupFolder.getCanonicalPath());
  • 检查父目录的可写性:Log.d("Backup", "Parent dir writable: " + backupFolder.getParentFile().canWrite());
  • 使用Android Studio的Device File Explorer查看目标父目录的权限状态,确认是否有写入权限。

5. 验证设备存储的实际状态

  • 虽然canBackup()检查了存储挂载状态,但可额外验证存储是否可移除:Log.d("Backup", "Is removable: " + Environment.isExternalStorageRemovable());,部分SD卡设备对根目录写入有额外限制。
  • 确认目标路径是否包含特殊字符、路径长度是否超出文件系统限制。

内容的提问来源于stack exchange,提问作者Scott van Duin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 10:14:58