Android(Kotlin)中目录树文件夹无法被listFiles()识别的问题
Android目录树遍历问题:listFiles()返回空列表的解决方案
核心错误原因
你这里的问题出在Uri使用错误:DocumentsContract.buildChildDocumentsUriUsingTree()生成的是用于通过ContentResolver查询子文档的Uri,而DocumentFile.fromTreeUri()需要的是用户授权的目录树本身的Uri(即方法参数里的directoryUri)。用子文档Uri创建的DocumentFile无法正确识别目录结构,自然返回空列表。
修正后的代码
直接使用原始的directoryUri初始化DocumentFile即可,无需额外构建childrenUri:
private fun processDirectoryPath(directoryUri: Uri) { Log.d("Folder Manager", "DEBUG?$directoryUri") // 直接用传入的目录树Uri创建DocumentFile,避免空指针风险 val docTree = DocumentFile.fromTreeUri(this, directoryUri) ?: run { Log.e("Folder Manager", "无法从Uri获取DocumentFile") return } val images = ArrayList<Pair<String, Bitmap>>() var errorFound = false // 一次性获取文件列表,避免重复调用耗时操作 val files = docTree.listFiles() if (files.isNotEmpty()) { for (doc in files) { if (doc.isDirectory && !errorFound) { // 你的目录处理逻辑 } } } // ... }
额外注意事项
- 权限验证:确保已通过存储访问框架(SAF)获取目标目录的读写权限;Android 11+访问外部存储根目录等特殊路径,需申请
MANAGE_EXTERNAL_STORAGE权限;Android 13+需针对媒体类型申请对应权限(如READ_MEDIA_IMAGES)。 - 性能优化:
DocumentFile的listFiles()是耗时操作,尽量一次获取后复用结果;如果需要遍历大量文件,建议直接用ContentResolver查询,避免DocumentFile的包装开销:
private fun queryDirectoryChildren(directoryUri: Uri) { val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree( directoryUri, DocumentsContract.getTreeDocumentId(directoryUri) ) contentResolver.query(childrenUri, null, null, null, null)?.use { cursor -> while (cursor.moveToNext()) { val docId = cursor.getString(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_DOCUMENT_ID)) val mimeType = cursor.getString(cursor.getColumnIndex(DocumentsContract.Document.COLUMN_MIME_TYPE)) if (DocumentsContract.Document.MIME_TYPE_DIR == mimeType) { // 处理文件夹逻辑 val childUri = DocumentsContract.buildDocumentUriUsingTree(directoryUri, docId) // 递归处理子目录等 } } } }
内容的提问来源于stack exchange,提问作者blessedsky
相关产品推荐
相关产品推荐

