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

如何通过子文件DocumentFile的Uri获取授权根目录并校验权限?

从文件Uri获取已授权根目录Uri的解决方案

针对通过Intent.ACTION_OPEN_DOCUMENT_TREE授权文件夹后,仅持有子文件Uri时,如何追溯到原授权目录Uri的问题,可通过以下原生API实现,无需正则修改Uri或额外保存目录树Uri:

实现逻辑

利用Android原生的DocumentsContract API解析文件的文档ID,递归向上遍历父节点,同时结合ContentResolver的持久化权限列表进行匹配,找到第一个属于已授权范围的目录树Uri。

示例代码(Kotlin)

import android.content.Context
import android.net.Uri
import android.provider.DocumentsContract

fun getAuthorizedRootUri(context: Context, fileUri: Uri): Uri? {
    val authority = fileUri.authority ?: return null
    var currentDocId = DocumentsContract.getDocumentId(fileUri)
    val persistedPermissions = context.contentResolver.persistedUriPermissions

    while (true) {
        // 构建当前节点的树Uri,与ACTION_OPEN_DOCUMENT_TREE返回的格式一致
        val currentTreeUri = DocumentsContract.buildTreeDocumentUri(authority, currentDocId)
        // 检查该Uri是否在已持久化的授权列表中
        if (persistedPermissions.any { it.uri == currentTreeUri }) {
            return currentTreeUri
        }

        // 获取父节点的文档ID,无父节点则终止循环
        val parentDocId = runCatching {
            DocumentsContract.getParentDocumentId(
                context.contentResolver,
                DocumentsContract.buildDocumentUri(authority, currentDocId)
            )
        }.getOrNull() ?: break

        currentDocId = parentDocId
    }
    return null
}

关键细节说明

  • DocumentsContract.getDocumentId():提取文件Uri对应的唯一文档标识,用于后续节点遍历。
  • DocumentsContract.buildTreeDocumentUri():将文档ID转换为树结构Uri,这是ACTION_OPEN_DOCUMENT_TREE返回的标准格式。
  • ContentResolver.persistedUriPermissions:获取应用已保存的所有文档权限Uri,确保找到的是用户主动授权的目录。
  • 异常捕获:通过runCatching处理无父节点或权限不足的情况,避免崩溃。

内容的提问来源于stack exchange,提问作者passerby

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:30:12