Android 11+下应用自有文件列表失效(compileSdk升级至35后)
我将mp3、mp4、jpg及应用自有aw格式文件存储在应用的cache目录中,使用如下代码清理临时文件:
private fun deleteTmp() { val rootFolder = File(context.cacheDir.absolutePath) val mp4 = ".*\\.mp4" val mp3 = ".*\\.mp3" val jpg = ".*\\.jpg" val gif = ".*\\.gif" val aw = ".*\\.aw" val folder = File("$rootFolder/") val files = folder.listFiles { _, name -> (name.matches(mp4.toRegex()) || name.matches(mp3.toRegex()) || name.matches(jpg.toRegex()) || name.matches(gif.toRegex()) || name.matches(aw.toRegex())) } if (files != null) { for (file in files) { file.delete() } } }
compileSdk从29升级至35前代码运行正常,升级后listFiles仅能获取文件夹,无法识别文件。已知访问应用自有文件无需权限,且这些文件均为自行创建。尝试使用filesDir无效,直接调用context.cacheDir.listFiles()同样仅返回文件夹(路径为/data/user/0/com.xxx.xxx/cache)。不想向用户申请权限,希望找到应用内部操作的解决方法。
改用Files.walk遍历目录
放弃listFiles,使用Java NIO的Files.walk遍历cache目录,高版本Android兼容性更好,能准确获取所有文件和文件夹,过滤目标格式后删除:private fun deleteTmp() { val cachePath = context.cacheDir.toPath() Files.walk(cachePath) .filter { path -> val fileName = path.fileName.toString() fileName.endsWith(".mp4") || fileName.endsWith(".mp3") || fileName.endsWith(".jpg") || fileName.endsWith(".gif") || fileName.endsWith(".aw") } .forEach { path -> try { Files.delete(path) } catch (e: IOException) { // 处理删除失败场景,比如文件被占用 e.printStackTrace() } } }检查文件实际存储路径
确认文件是否真的在cacheDir根目录,而非子文件夹。升级compileSdk后,部分文件创建逻辑可能因路径处理变化导致文件存入子目录,原代码仅遍历根目录会遗漏。可打印cache目录所有内容验证:private fun checkCacheFiles() { Files.walk(context.cacheDir.toPath()) .forEach { path -> Log.d("CacheFileCheck", path.toString()) } }若文件在子目录,需调整遍历范围或修改文件创建时的存储路径。
替换listFiles的过滤器逻辑
改用FileFilter直接判断File对象是否为文件且符合后缀,避免仅通过文件名匹配的误判:private fun deleteTmp() { val folder = context.cacheDir val files = folder.listFiles { file -> file.isFile && ( file.name.endsWith(".mp4") || file.name.endsWith(".mp3") || file.name.endsWith(".jpg") || file.name.endsWith(".gif") || file.name.endsWith(".aw") ) } files?.forEach { it.delete() } }同步升级targetSdkVersion
若仅升级compileSdk而targetSdkVersion停留在29,可能出现行为不一致。建议将targetSdkVersion同步升级到35,确保应用行为符合高版本Android规范,减少兼容性问题。
内容的提问来源于stack exchange,提问作者Diego Perez

