如何获取DocumentFile的目录Uri以适配EXTRA_INITIAL_URI?
问题分析
你遇到的核心问题是:持久化的目录Uri是Document类型(格式如content://.../document/primary:save/newDirectory),而DocumentsContract.EXTRA_INITIAL_URI要求传入的是Tree类型的目录Uri(格式如content://.../tree/primary:save/newDirectory)。系统无法识别Document类型Uri作为初始目录,因此默认跳转到用户最初选择的父目录。
解决方案
需要将持久化的Document Uri转换为对应的Tree Uri,具体步骤如下:
- 编写Uri转换函数,从Document Uri中提取目录的Tree Uri:
fun convertDocumentUriToTreeUri(documentUri: Uri): Uri? { val documentId = DocumentsContract.getDocumentId(documentUri) val treeUri = DocumentsContract.buildTreeDocumentUri( documentUri.authority, documentId ) return treeUri }
- 修改文件选择器的代码,使用转换后的Tree Uri作为初始目录:
// 从DataStore读取持久化的document Uri val localSaveFileDirectory = // 你的读取逻辑 val targetTreeUri = convertDocumentUriToTreeUri(localSaveFileDirectory) val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) putExtra(Intent.EXTRA_TITLE, "test.csv") // 若要跳转到dir1,基于newDirectory的tree Uri构造dir1的tree Uri targetTreeUri?.let { treeUri -> val dir1TreeUri = DocumentsContract.buildTreeDocumentUri( treeUri.authority, "${DocumentsContract.getTreeDocumentId(treeUri)}/dir1" ) putExtra(DocumentsContract.EXTRA_INITIAL_URI, dir1TreeUri) } type = "*/*" } launcherRead.launch(intent)
补充说明
- Tree类型Uri用于表示整个目录树的访问入口,而Document类型Uri仅指向单个文件/目录的具体条目,两者格式和用途不同。
- 转换时需确保你持有该目录的持久化访问权限(通过
takePersistableUriPermission获取,你应该已经在选择目录时处理过这一步)。
内容的提问来源于stack exchange,提问作者Ilya P.
相关产品推荐
相关产品推荐

