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)
        }
    }

}
相关推荐
csj507 分钟前
安卓基础之《(21)—高级控件(3)翻页类视图》
android
2501_9159184111 分钟前
中小团队发布,跨平台 iOS 上架,证书、描述文件创建管理,测试分发一体化方案
android·ios·小程序·https·uni-app·iphone·webview
betazhou34 分钟前
MySQL相关性能查询语句
android·数据库·mysql
一起养小猫40 分钟前
Flutter for OpenHarmony 进阶:Timer组件与倒计时系统深度解析
android·网络·笔记·flutter·json·harmonyos
符哥20081 小时前
Fastjson2.X 使用详解
android·java
月明泉清1 小时前
Android中对于点击事件的深度梳理(三)
android
电饭叔1 小时前
DataFrame和 Series 索引
android·python
lexiangqicheng1 小时前
【全网最全】React Native 安卓原生工程结构与构建机制深度解析
android·react native·react.js
数据蜂巢2 小时前
MySQL 8.0 生产环境备份脚本 (Percona XtraBackup 8.0+)
android·mysql·adb
jingling5552 小时前
uniapp | 基于高德地图实现位置选择功能(安卓端)
android·前端·javascript·uni-app