如何编程获取目录下所有文件名?list()无法获取.zip/.apk文件
问题根因
File.list()原生API本身不会根据文件后缀做过滤,无法获取.zip、.apk格式文件通常由以下原因导致:
- 路径属于Android外部存储非沙盒目录,在Android 10及以上版本的分区存储机制下,系统默认对压缩包、安装包类文件做访问保护,普通应用无权限直接通过Java File API枚举这类受管控的文件
- 目标目录下的.zip、.apk为隐藏文件(文件名以
.开头),或代码中存在未注意到的后缀过滤逻辑 - 部分国产定制ROM对APK安装包、压缩包文件设置了额外权限拦截,未获得对应授权时读取会被系统屏蔽
可落地解决方案
根据你的实际使用场景选对应方案即可:
分区存储环境适配(Android 10+)
如果目标路径是外部存储公共目录,不要直接使用java.io.File系列API枚举文件,改用系统MediaStore接口查询全量文件,可正常获取zip、apk格式文件:
val fileList = mutableListOf<String>() val contentUri = MediaStore.Files.getContentUri("external") val projection = arrayOf( MediaStore.Files.FileColumns.DISPLAY_NAME, MediaStore.Files.FileColumns.DATA ) // 替换为你的目标目录对应的父ID筛选条件 val selection = "${MediaStore.Files.FileColumns.PARENT} = ?" val selectionArgs = arrayOf(targetDirectoryId.toString()) contentResolver.query(contentUri, projection, selection, selectionArgs, null)?.use { cursor -> val nameColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME) while (cursor.moveToNext()) { fileList.add(cursor.getString(nameColumnIndex)) } }
如果你的应用需要在Android 11及以上版本访问外部存储全量文件,可以在清单中声明MANAGE_EXTERNAL_STORAGE权限,引导用户开启「所有文件访问权限」后,再调用File.list()即可获取全量文件名。
权限校验与过滤逻辑排查
如果目标路径是应用私有目录、或已经获得全量存储授权,先检查代码中是否存在对返回结果的后缀名过滤逻辑;如果需要读取隐藏文件,不要过滤文件名以.开头的条目,可直接使用无过滤器的listFiles()方法获取全量文件:
val fileDir = File(folder) // 包含隐藏文件在内的所有文件,无额外过滤 val files = fileDir.listFiles()?.map { it.name } ?: return null
定制ROM特殊适配
针对小米、华为等存在额外权限管控的ROM,需要额外引导用户开启「安装未知应用」「读取文件内容」等相关权限,解除系统对APK、ZIP类文件的读取拦截后即可正常获取对应文件。
内容的提问来源于stack exchange,提问作者Arthurghev
相关产品推荐
相关产品推荐

