Android API29 二级外部存储(SD卡)调用mkdir()返回false问题排查
Android 10(API29)SD卡创建目录失败原因及解决方案
核心原因
- 即使开启了
android:requestLegacyExternalStorage="true",WRITE_EXTERNAL_STORAGE权限也仅能授权访问内置公共存储区域,无法授予外置SD卡任意路径的写入权限,这是Android分区存储机制的强制限制。 - 你当前的代码通过多次调用
parentFile跳转到SD卡根目录创建文件夹,该路径不属于应用专属存储范围,传统FileAPI无写入权限,因此mkdir()返回false。 ContextCompat.getExternalFilesDirs返回的第二个路径是SD卡上的应用专属存储目录,该路径下你拥有完整读写权限,不需要额外申请权限,但向上跳转父目录后就超出了权限范围。
解决方案
场景1:仅需在SD卡存储应用私有数据
直接在SD卡的应用专属目录下创建文件夹即可,不需要跳转到根目录:
val externalFiles = ContextCompat.getExternalFilesDirs(this, null) // 先判断是否存在外置SD卡 if (externalFiles.size >= 2 && externalFiles[1] != null) { val sdCardAppDir = externalFiles[1] val myDirectory = File(sdCardAppDir, "Folder") if (!myDirectory.exists()) { val createResult = myDirectory.mkdir() Log.i("Create", createResult.toString()) } }
场景2:需要在SD卡公共区域创建用户可见的目录
必须使用系统存储访问框架(SAF)主动申请SD卡的访问权限,步骤如下:
- 触发授权弹窗让用户选择SD卡根目录:
val REQUEST_CODE_SD_PERM = 1001 // 替换为你的SD卡标识,也可以不传初始Uri让用户手动选择 val sdCardUri = Uri.parse("content://com.android.externalstorage.documents/tree/3C03-69OD%3A") val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { putExtra(DocumentsContract.EXTRA_INITIAL_URI, sdCardUri) } startActivityForResult(intent, REQUEST_CODE_SD_PERM)
- 接收授权结果,使用
DocumentFile创建目录:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE_SD_PERM && resultCode == Activity.RESULT_OK) { val treeUri = data?.data ?: return // 持久化保存权限,下次启动应用无需重复申请 contentResolver.takePersistableUriPermission( treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION ) val sdRoot = DocumentFile.fromTreeUri(this, treeUri) // 创建Folder目录 val newFolder = sdRoot?.createDirectory("Folder") Log.i("Create", (newFolder != null && newFolder.exists()).toString()) } }
注意事项
- 若后续将应用目标版本升级到API30及以上,
requestLegacyExternalStorage配置会完全失效,所有公共存储区域的写入操作都需要使用SAF或者MediaStore实现,无法再通过传统FileAPI操作。 - 使用
getExternalFilesDirs之前务必先判断数组长度,避免用户未插入SD卡时出现空指针崩溃。
内容的提问来源于stack exchange,提问作者Satyaki Sen
相关产品推荐
相关产品推荐

