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

使用DocumentsContract.createDocument时出现Invalid URI异常的问题

目录选择后创建文件报错的排查与解决

问题场景

使用Kotlin和Jetpack Compose开发Android应用,实现用户选择目录后在其中创建并写入文本文件的功能,执行目录选择操作后触发以下异常:

Failed to create document
java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/primary%3ADownload%2FTest
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
    at android.content.ContentProviderProxy.call(ContentProviderNative.java:764)
    at android.content.ContentResolver.call(ContentResolver.java:2466)
    at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1380)

问题原因

OpenDocumentTree返回的是目录的Tree URI(格式如content://.../tree/...),而DocumentsContract.createDocument方法要求传入的是目录的Document URI(格式如content://.../document/...),两者格式不匹配导致参数无效。

解决方案

将选中目录的Tree URI转换为对应的Document URI后,再调用createDocument方法。修改createFileInDirectory函数如下:

fun createFileInDirectory(context: Context, parentUri: Uri) {
    val contentResolver = context.contentResolver
    val mimeType = "text/plain"
    val displayName = "example.txt"

    try {
        // 将Tree URI转换为Document URI
        val documentId = DocumentsContract.getTreeDocumentId(parentUri)
        val documentUri = DocumentsContract.buildDocumentUriUsingTree(parentUri, documentId)
        
        // 在转换后的Document URI对应的目录下创建文件
        val newDocumentUri = DocumentsContract.createDocument(
            contentResolver,
            documentUri,
            mimeType,
            displayName
        )

        newDocumentUri?.let {
            writeToFile(context, it)
        }
    } catch (e: Exception) {
        Toast.makeText(context, "Error creating file: ${e.message}", Toast.LENGTH_LONG).show()
    }
}

原理说明

  • Tree URI是系统用于授予应用对整个目录树访问权限的标识,无法直接用于创建子文档
  • 通过DocumentsContract.getTreeDocumentId提取Tree URI中的文档ID,再用DocumentsContract.buildDocumentUriUsingTree构建出对应目录的Document URI,该URI代表具体的目录节点,可用于创建子文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:26:00