Android从raw目录获取MP3文件失败问题求助
问题分析与解决方案
核心问题点
- 资源目录混淆:你通过
res.assets.list("raw")尝试读取res/raw目录,但assets.list()仅能访问src/main/assets下的文件,和res/raw是完全独立的资源目录,因此无法获取目标MP3文件。 - 反射判断逻辑错误:
res/raw中的资源会被Android编译为不带后缀的字段名(例如test.mp3会生成R.raw.test),你的代码里fieldName.endsWith(".mp3")的判断条件永远无法匹配,导致过滤不到任何资源。
修正方案
方案1:修正反射方法(推荐,更可靠)
移除后缀判断逻辑,直接遍历R.raw的所有int类型字段,这些字段对应res/raw下所有资源的ID:
class MP3Provider(private val context: Context) { fun getMp3List(): List<mp3> { val mp3List = mutableListOf<mp3>() val rawFields = R.raw::class.java.fields rawFields.forEachIndexed { index, field -> if (field.type == Int::class.java) { val resourceId = field.getInt(null) // 通过资源ID获取原始文件名(不带后缀) val title = context.resources.getResourceEntryName(resourceId) mp3List.add( mp3( id = index, rawResourceId = resourceId, title = title, isPlaying = false ) ) } } return mp3List } }
方案2:非反射批量获取(需提前知晓文件名)
如果明确知道res/raw下的MP3文件名(不带后缀),可以批量构建列表,但这种方式灵活性较低:
class MP3Provider(private val context: Context) { fun getMp3List(): List<mp3> { val mp3List = mutableListOf<mp3>() // 假设已知文件名列表(不带.mp3后缀) val mp3FileNames = listOf("audio1", "audio2", "audio3") mp3FileNames.forEachIndexed { index, fileName -> val resourceId = context.resources.getIdentifier(fileName, "raw", context.packageName) if (resourceId != 0) { // 资源存在时才添加 mp3List.add( mp3( id = index, rawResourceId = resourceId, title = fileName, isPlaying = false ) ) } } return mp3List } }
额外检查项
- 确保
res/raw下的MP3文件名符合Android资源命名规范:仅能包含小写字母、数字、下划线和点,不能有空格或大写字母,否则会导致编译异常或资源无法识别。 - 执行
File -> Sync Project with Gradle Files同步资源,确认Android Studio已正确索引res/raw中的文件。 - 测试时可先打印
rawFields.size(反射方案),确认是否能获取到R.raw的字段数量,排查资源是否被正确编译。
内容的提问来源于stack exchange,提问作者Rdog420
相关产品推荐
相关产品推荐

