使用OpenDocumentTree获取的URI调用DocumentsContract.getDocumentId报错
解决OpenDocumentTree获取URI后getDocumentId抛出异常的问题
你遇到的异常是因为部分设备返回的外部存储根目录URI格式无法被DocumentsContract.getDocumentId()正确解析,以下是两种可行的解决方法:
方法一:兼容低版本的手动提取DocumentId
当getDocumentId()抛出异常时,直接从URI路径中提取并解码tree后的部分作为DocumentId:
private val dirRequest = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> uri?.let { val documentId = try { DocumentsContract.getDocumentId(it) } catch (e: IllegalArgumentException) { // 手动提取并解码DocumentId val pathSegment = it.path?.substringAfter("/tree/") ?: "" Uri.decode(pathSegment) } if (documentId.isNotBlank()) { val childDocumentsUri = DocumentsContract.buildChildDocumentsUriUsingTree(it, documentId) // 这里执行后续操作 } } }
方法二:API 26+专用方法
从Android 8.0(API 26)开始,系统提供了专门针对tree类型URI的getTreeDocumentId()方法,无需担心解析异常:
private val dirRequest = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri -> uri?.let { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val documentId = DocumentsContract.getTreeDocumentId(it) val childDocumentsUri = DocumentsContract.buildChildDocumentsUriUsingTree(it, documentId) // 后续操作 } else { // 低版本回退到方法一的逻辑 val documentId = try { DocumentsContract.getDocumentId(it) } catch (e: IllegalArgumentException) { val pathSegment = it.path?.substringAfter("/tree/") ?: "" Uri.decode(pathSegment) } val childDocumentsUri = DocumentsContract.buildChildDocumentsUriUsingTree(it, documentId) // 后续操作 } } }
说明
异常中的URIcontent://com.android.externalstorage.documents/tree/9C33-6BBD%3AA解码后是9C33-6BBD:A,这是外部存储根目录的DocumentId,手动提取或用getTreeDocumentId()都能正确获取到该值,进而正常调用buildChildDocumentsUriUsingTree()。
内容的提问来源于stack exchange,提问作者Cyber Avater
相关产品推荐
相关产品推荐

