Android获取全部音乐文件异常:仅返回部分文件的问题排查
问题原因及解决方案
核心错误:查询条件字段匹配完全错误
你的代码里查询条件用错了字段,这是导致无法获取全部音乐的直接原因:
val selection = Audio.Media.DISPLAY_NAME + " >= ?" val selectionArgs = arrayOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES).toString())
这里把代表音频时长的Audio.Media.DURATION字段,错误写成了代表文件名的Audio.Media.DISPLAY_NAME,相当于用文件名和时长数值做比较,逻辑完全混乱,导致绝大多数音乐被错误过滤。
正确的查询条件应该是:
val selection = Audio.Media.DURATION + " >= ?" val selectionArgs = arrayOf(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES).toString())
其他可能导致漏获取音乐的原因
- 权限缺失:Android 13及以上需要声明并动态申请
READ_MEDIA_AUDIO权限;Android 12及以下需要READ_EXTERNAL_STORAGE权限,确保权限已正确获取。 - 未过滤非音乐音频:
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI会返回所有音频文件(比如铃声、通知音、语音备忘录),如果只想获取音乐,需添加额外过滤条件:val selection = "${Audio.Media.DURATION} >= ? AND ${Audio.Media.IS_MUSIC} = 1" - 媒体库未完成索引:刚存入手机的音乐可能还未被系统媒体库扫描到,需等待扫描完成,或手动触发媒体扫描。
- Cursor空指针风险:代码中直接使用
cursor!!,若查询返回null会引发崩溃,建议添加非空判断并使用use块自动关闭Cursor:cursor?.use { val idColumn = it.getColumnIndexOrThrow(Audio.Media._ID) val nameColumn = it.getColumnIndexOrThrow(Audio.Media.DISPLAY_NAME) val durationColumn = it.getColumnIndexOrThrow(Audio.Media.DURATION) val sizeColumn = it.getColumnIndexOrThrow(Audio.Media.SIZE) while (it.moveToNext()) { val id = it.getLong(idColumn) val name = it.getString(nameColumn) val duration = it.getInt(durationColumn) val size = it.getInt(sizeColumn) val contentUri = ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI, id) arrayList.add(AudioModel(contentUri.toString(), name, duration)) } }
内容的提问来源于stack exchange,提问作者ibrahim akbas
相关产品推荐
相关产品推荐

