Kotlin中如何通过OPEN_DOCUMENT_TREE获取完整目录路径?
获取OPEN_DOCUMENT_TREE选中目录的完整路径
你的问题出在直接用Environment.getExternalStorageDirectory()拼接DocumentFile.name——DocumentFile.name本来就只返回当前目录的最后一级名称,没法拿到中间层级。下面给两种可行的解决方法:
方法一:递归遍历父节点拼接路径
通过递归获取选中目录的所有父节点,反向拼接出完整的相对路径,再和外部存储根路径组合:
// 递归获取完整相对路径 fun getFullDocumentPath(documentFile: DocumentFile): String { val pathSegments = mutableListOf<String>() var currentDoc = documentFile // 向上遍历所有父目录 while (true) { currentDoc.name?.let { pathSegments.add(it) } ?: break currentDoc.parentFile?.let { currentDoc = it } ?: break } // 反转后拼接成路径 return pathSegments.reversed().joinToString("/") } // 在onActivityResult中使用 if (requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK) { data?.data?.also { uri -> val selectedDirectory = DocumentFile.fromTreeUri(activity, uri) ?: return val fullRelativePath = getFullDocumentPath(selectedDirectory) val storageRoot = Environment.getExternalStorageDirectory().absolutePath val fullPath = "$storageRoot/$fullRelativePath" // 注意:Android 10+不推荐直接用绝对路径操作文件,优先用DocumentFile/Uri } }
方法二:解析DocumentsContract的文档ID(适用于Android 10以下或已申请全存储权限)
OPEN_DOCUMENT_TREE返回的Uri对应的文档ID格式通常是primary:Download/test,通过分割这个ID可以直接拿到相对路径:
// 从TreeUri解析完整路径 fun getFullPathFromTreeUri(treeUri: Uri, context: Context): String? { val docId = DocumentsContract.getTreeDocumentId(treeUri) val splitId = docId.split(":") if (splitId.size < 2) return null val storageType = splitId[0] val relativePath = splitId[1] // 处理主外部存储 if ("primary".equals(storageType, ignoreCase = true)) { return "${Environment.getExternalStorageDirectory().absolutePath}/$relativePath" } // 如果需要处理SD卡等其他存储,需要额外适配逻辑,这里仅示例主存储 return null } // 在onActivityResult中使用 if (requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK) { data?.data?.also { uri -> val fullPath = getFullPathFromTreeUri(uri, activity) fullPath?.let { // 拿到完整路径后进行操作 } } }
重要提醒
从Android 10(API 29)开始,Scoped Storage限制了直接访问绝对路径,推荐优先使用DocumentFile或Uri进行文件操作,避免权限适配问题。如果业务必须用绝对路径,需要在AndroidManifest.xml中申请MANAGE_EXTERNAL_STORAGE权限,并引导用户在系统设置中授权。
内容的提问来源于stack exchange,提问作者Jared Davenport
相关产品推荐
相关产品推荐

