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

Android:从CONTENT URI获取同目录文件及访问ownCloud目录

解决两个ownCloud文件访问问题:同目录文件获取与目录选择

一、从单个文件Content URI获取同目录文件列表

第三方文档Provider(如ownCloud)的URI结构和MediaStore差异较大,不能直接用常规MediaStore字段查询目录文件,需通过DocumentsContract接口处理:

步骤1:解析当前文件的父目录ID/URI

ownCloud的文档ID通常格式为父目录ID/文件ID(比如示例URIcontent://org.owncloud.documents/document/79对应的文档ID可能是78/79),可通过以下方式获取父目录信息:

import android.provider.DocumentsContract

// 1. 获取当前文件的文档ID
val docId = DocumentsContract.getDocumentId(uri)
// 2. 拆分文档ID得到父目录ID(根据ownCloud格式调整)
val parentDocId = docId.split("/").firstOrNull() ?: return
// 3. 构造父目录的Content URI
val parentDirUri = DocumentsContract.buildDocumentUri("org.owncloud.documents", parentDocId)

如果拆分方式不适用,也可以直接查询当前文件的父目录ID字段:

val projection = arrayOf(DocumentsContract.Document.COLUMN_PARENT_DOCUMENT_ID)
context.contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
    if (cursor.moveToFirst()) {
        val parentDocId = cursor.getString(cursor.getColumnIndexOrThrow(
            DocumentsContract.Document.COLUMN_PARENT_DOCUMENT_ID
        ))
        val parentDirUri = DocumentsContract.buildDocumentUri("org.owncloud.documents", parentDocId)
        // 后续查询父目录文件
    }
}

步骤2:查询父目录下的所有文件

用构造好的父目录URI查询子文件,使用DocumentsContract标准列(避免用MediaStore的DATA字段,第三方Provider可能不支持):

val fileProjection = arrayOf(
    DocumentsContract.Document.COLUMN_DISPLAY_NAME,
    DocumentsContract.Document.COLUMN_DOCUMENT_ID,
    DocumentsContract.Document.COLUMN_MIME_TYPE
)

context.contentResolver.query(parentDirUri, fileProjection, null, null, null)?.use { cursor ->
    while (cursor.moveToNext()) {
        val fileName = cursor.getString(cursor.getColumnIndexOrThrow(
            DocumentsContract.Document.COLUMN_DISPLAY_NAME
        ))
        val fileDocId = cursor.getString(cursor.getColumnIndexOrThrow(
            DocumentsContract.Document.COLUMN_DOCUMENT_ID
        ))
        // 构造单个文件的Content URI
        val fileUri = DocumentsContract.buildDocumentUri("org.owncloud.documents", fileDocId)
        
        // 处理文件信息(如存入列表)
    }
}

二、解决ACTION_OPEN_DOCUMENT_TREE无法访问ownCloud的问题

ACTION_OPEN_DOCUMENT_TREE无法识别ownCloud,通常是因为ownCloud的DocumentsProvider未适配该Intent,可尝试以下方案:

  • 更新ownCloud应用:部分旧版本ownCloud未实现目录选择支持,更新到最新版本后可能解决。
  • 替代方案:批量选择文件:使用ACTION_GET_CONTENT并开启多选,让用户手动选择同目录文件:
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    startActivityForResult(intent, REQUEST_CODE_PICK_FILES)
    
  • 申请父目录持久权限:如果已经通过单个文件URI获得访问权限,可对父目录申请持久化权限,后续直接通过代码访问目录:
    val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
    try {
        context.contentResolver.takePersistableUriPermission(parentDirUri, flags)
    } catch (e: SecurityException) {
        // 处理权限申请失败
    }
    
  • 查看ownCloud自定义Intent:部分应用会提供自定义Intent用于目录选择,可查阅ownCloud官方开发者文档寻找对应接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:40:25