Android开发中无法获取ACTION_OPEN_DOCUMENT_TREE选择结果的子目录
核心原因
DocumentFile.fromTreeUri() 本身不提供自动递归遍历全目录树的能力,该方法仅返回用户选中的根目录对应的DocumentFile实例,直接调用listFiles()仅能获取当前目录层级下的直接子项,不会自动深入嵌套的子目录,必须手动实现递归遍历逻辑才能拿到所有层级的文件、文件夹。
修正后的实现代码
你的目录唤起逻辑没有问题,只需要替换遍历方法为递归版本即可:
private fun walkTree(uri: Uri) { val rootDocument = DocumentFile.fromTreeUri(requireContext(), uri) ?: return traverseChildItems(rootDocument) } /** * 递归遍历目录下所有层级的内容 */ private fun traverseChildItems(document: DocumentFile) { document.listFiles().forEach { item -> Timber.d("项URI: ${item.uri},类型: ${if (item.isDirectory) "文件夹" else "文件"}") // 识别到子文件夹时,递归进入遍历内部内容 if (item.isDirectory) { traverseChildItems(item) } } }
注意事项
- 拿到目录选择返回的Uri后,建议第一时间申请持久化访问权限,否则应用重启后临时授权失效,会无法读取对应目录内容:
// 在resultLauncher的回调中执行 val permissionFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION requireContext().contentResolver.takePersistableUriPermission(returnedUri, permissionFlags)
- 遍历逻辑禁止放在主线程执行,目录内文件数量较多时会阻塞UI触发ANR,建议放到协程IO线程、后台任务中运行。
- Android 11及以上版本不需要额外申请全局读写存储权限,SAF框架返回的访问权限不受分区存储的全局权限限制。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

