Android中获取设备里面的音频文件

前言

本文用来记录如何获取手机设备中存储的音频文件,之后可以通过各种播放器进行播放。


audio介绍

用下面工具类来获取系统提供的ContentProvider中数据库里的音频文件,然后自由选择每条记录的所需的属性并存储在Bean类中,就可以通过实体类随意使用了。

kotlin 复制代码
1.工具类:
//工具类,目前固定获取手机中音频文件中容量、歌曲名、歌手属性,后续考虑修改扩展性更强的工具类
object GetQueryAudioUtils {

    suspend fun getQueryAudio(
        context: Context
    ): List<AudioBean> = withContext(Dispatchers.IO) {
        val resolver = context.contentResolver //获取contentResolver
        val queryResult = mutableListOf<AudioBean>() //存放查询结果

        val projection = arrayOf(
            //查询的属性列表
            MediaStore.Audio.Media._ID, //拼uri 必定存在的列 不会出现找不到的异常
            MediaStore.Audio.Media.SIZE, //容量
            MediaStore.Audio.Media.DISPLAY_NAME, //含扩展名的歌曲名
            MediaStore.Audio.Media.ARTIST, //歌手
        )

        runCatching {
            resolver.query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                //获取到路径  容量  歌曲名  歌手
                projection,
                null,
                null,
                null
            )?.use { cursor -> //可以自动关流

                //获取对应属性在表中具体第几列的序列号index
                val idIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID) //防止意外抛出异常
                val sizeIndex = cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)
                val nameIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)
                val artisIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)

                while (cursor.moveToNext()) {
                    //对查询后的结果进行包装实体类
                    val id = cursor.getLong(idIndex)
                    val size = if (sizeIndex != -1) cursor.getLong(sizeIndex) else 0
                    val songName = if (nameIndex != -1) cursor.getString(nameIndex)
                        ?.substringBeforeLast('.') ?: "未知歌曲" else "未知歌曲"
                    val singer = if (artisIndex != -1) cursor.getString(artisIndex)
                        ?: "未知歌手" else "未知歌手"

                    val uri =
                        ContentUris.withAppendedId(
                            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id
                        ) //将获取到的id拼接在contentProvider地址的后面

                    queryResult.add(AudioBean(uri, size, songName, singer))
                }
            }
            queryResult
        }.onFailure {
            Log.e("GetQueryAudioUtils", "query audio failed", it)
        }.getOrDefault(emptyList<AudioBean>())

    }
}


2.使用:
  //清单文件中添加权限
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!--api33及以上-->
    <!-- 外部存储读取权限 -->
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" /><!--api29-32-->


//mainActivity
class MainActivity : BaseActivity() {
    private lateinit var text: TextView

    override fun setViewId(): Int = R.layout.activity_main

    override fun initView() {
        text = findViewById(R.id.text)

        //动态获取权限
        PremissionUtils.requestPermissions(this)

        lifecycleScope.launch(Dispatchers.Main) {
            val result: List<AudioBean> = GetQueryAudioUtils.getQueryAudio(this@MainActivity)
            if (result.isNotEmpty())
                text.text = result.toString()
        }
    }
}



//3.动态权限申请
object PremissionUtils {

    var PERMISSIONS_STORAGE: Array<String?> = arrayOf<String?>(
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ) //Android6.0以后操作系统的动态权限申请


    /**
     * 用于Android6.0以后的操作系统,动态申请存储的读写权限
     * @param context
     */
    fun requestPermissions(context: Activity) {
        //用于Android6.0以后的操作系统,动态申请存储的读写权限
        val permission =
            ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(context, PERMISSIONS_STORAGE, 1)
        }
    }

}
相关推荐
lpruoyu1 天前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
独自破碎E1 天前
【BISHI15】小红的夹吃棋
android·java·开发语言
李堇1 天前
android滚动列表VerticalRollingTextView
android·java
lxysbly1 天前
n64模拟器安卓版带金手指2026
android
游戏开发爱好者81 天前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20351 天前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥1 天前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓1 天前
[JDBC]元数据
android
独行soc1 天前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能1 天前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio