Android获取设备中本地音频

文章目录


前言

Android开发中经常需要获取当前设备中的音频文件,用来播放等操作,于是写了一个工具类可以直接拿来使用,避免了每次手写,提高代码开发的效率。


工具类,可针对需求自行调节细节

kotlin 复制代码
object MusicRepository {

    /**
     *  @describe: 获取本地的音频数据
     *  @params:
     *    context:上下文
     *    externalScope:协程
     *  @return:
     */

   suspend fun getLocalMusic(context: Context): List<Song> = withContext(
        Dispatchers.IO){
        val result = mutableListOf<Song>()
        runCatching {
                //定义要查询的字段
                val projection = arrayOf(
                    MediaStore.Audio.Media._ID,             // 唯一ID
                    MediaStore.Audio.Media.TITLE,           // 标题
                    MediaStore.Audio.Media.ARTIST,          // 歌手
                    MediaStore.Audio.Media.ALBUM,           // 专辑
                    MediaStore.Audio.Media.DURATION,        // 时长
                    MediaStore.Audio.Media.DATA,            // 文件路径(Android 10+ 需注意分区存储)
                    MediaStore.Audio.Media.SIZE             // 文件大小
                )
                //设置筛选条件:只保留音乐文件(排除掉铃声、通知等)  时长>10秒(过滤短音频)
                val selection =
                    "${MediaStore.Audio.Media.IS_MUSIC} = 1 AND ${MediaStore.Audio.Media.DURATION} > 10000"
                //排序:按标题升序
                val sortOrder = "${MediaStore.Audio.Media.TITLE} ASC"
                //查询媒体库
                val cursor = context.contentResolver.query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, //查询的数据源URI:外部存储音频
                    projection,//需要返回的列
                    selection, //过滤的条件
                    null, //过滤条件的参数值
                    sortOrder //排序
                )
                //解析Cursor的查询结果
                cursor?.use { //use{}可以自动关闭cursor避免内存泄漏
                    //获取列表中目标列名所对应的位置position
                    val idColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
                    val titleColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)
                    val artistColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)
                    val albumColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)
                    val durationColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)
                    val pathColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
                    val sizeColumn = it.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)

                    while (it.moveToNext()) {
                        //跟据列号获取当前行中对应位置的具体数据(即行+列直接对应到具体位置)
                        val id = it.getLong(idColumn)
                        val title = it.getStringOrNull(titleColumn)
                        val artist = it.getStringOrNull(artistColumn)
                        val album = it.getStringOrNull(albumColumn)
                        val duration = it.getLongOrNull(durationColumn)
                        val path = it.getStringOrNull(pathColumn)
                        val size = it.getLongOrNull(sizeColumn)

                        //将获取到的数据存储起来
                        result.add(Song(id, title, if(artist == "<unknown>") "未知歌手" else artist, album, duration, path, size))
                    }
                }

            }.getOrNull()

        return@withContext result.toList()
    }
}

/**
 *  @describe: 歌曲的数据类
 *  @params:
 *  @return:
 */
data class Song(
    val id: Long,             // 媒体库唯一ID
    val title: String?,        // 音乐标题
    val artist: String?,       // 歌手名
    val album: String?,        // 专辑名
    val duration: Long?,       // 时长(毫秒)
    val path: String?,         // 音频文件路径
    val size: Long?            // 文件大小(字节)
)

activity中使用:

注意需要动态申请权限,Android13及以上权限为READ_MEDIA_AUDIO,以下为READ_EXTERNAL_STORAGE

kotlin 复制代码
 lifecycleScope.launch { //此处默认为主线程
     data = MusicRepository.getLocalMusic(this@MainActivity)
     data?.let {
       musicTitle.text = it[0].title
       musicSinger.text = it[0].artist
       val intent = Intent(this@MainActivity, AudioService::class.java).apply {
             putExtra("uri",it[0].path)
             putExtra("title",it[0].title)
             putExtra("artist",it[0].artist)
                          }
                      }
                    }
相关推荐
NiceCloud喜云4 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
南山有乔木7895 小时前
网易云音乐下载的ncm歌曲怎么转换MP3?本地播放可以这样整理
音视频
weixin_468466857 小时前
MoneyPrinterTurbo 短视频自动化生产实战指南
运维·人工智能·自动化·大模型·音视频·moneyprinter
潜创微科技8 小时前
2026年高清音视频KVM方案厂家洞察:市场格局选型逻辑与核心玩家解析
音视频
日光明媚8 小时前
一步生成视频!One-Forcing:DMD + 零成本 GAN,训练 200 步超越多步 SOTA
android·开发语言·kotlin
潜创微科技8 小时前
IT68353:DP 1.4 + HDMI 2.0 + USB-C 三合一转 HDMI 2.0 单芯片KVM切换方案
嵌入式硬件·音视频
XINERTEL9 小时前
视频卡顿花屏?专业视频质量评估测试让画质从“凭感觉”到“数据说话”
网络·测试工具·音视频·丢包
帅次9 小时前
Android 17 开发者实战:核心更新与应用场景落地指南
android·java·ios·android studio·iphone·android jetpack·webview
大鹏说大话9 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
bug和崩溃我都要10 小时前
Qt 封装 libmpv 全功能视频播放器开发指南
开发语言·qt·音视频