android 使用MediaPlayer实现音乐播放--获取音乐数据
前面已经添加了权限,有权限后可以去数据库读取音乐文件,一般可以获取全部音乐、专辑、歌手、流派等。
1. 获取全部音乐数据
class MusicHelper {companion object {@SuppressLint("Range")fun getMusic(context: Context): MutableList<MusicData> {var songNumber = 0val songsList: MutableList<MusicData> = ArrayList() //用于装歌曲数据val contentResolver: ContentResolver = context.contentResolvervar cursor: Cursor? = nulltry {cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null, null, null);if (cursor != null) {while (cursor.moveToNext()) {//是否是音频val isMusic =cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC))//时长val duration =cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))//是音乐并且时长大于30秒if (isMusic != 0 && duration >= 30 * 1000) {//歌名val title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE))//歌手val artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));//专辑idval albumId =cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))//文件路径val dataPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA))val data: String =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DATA))val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID))val music = MusicData(id, -1, albumId, title, artist, "", data, duration, songNumber, dataPath)songsList.add(music)songNumber++}}}} catch (e: Exception) {e.printStackTrace();} finally {cursor?.close()}return songsList}}
}
数据类MusicData
import java.io.Serializabledata class MusicData(val id: Long,val artistId: Int,val albumId: Long,val title: String,val artist: String,val album: String,val data:String,val duration: Long,val songSize: Int,val path:String
) : Serializable
2. 获取流派音乐数据
/*** 获取所有流派** @param context* @return*/@SuppressLint("Range")fun getGenres(context: Context): List<GenresData?> {val cursor = context.contentResolver.query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, null, null, null, null)var genresList: MutableList<GenresData?> = ArrayList()if (cursor != null) {genresList = java.util.ArrayList(cursor.count)while (cursor.moveToNext()) {val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Genres._ID))val name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Genres.NAME))genresList.add(GenresData(id, name))}cursor.close()}return genresList}
数据类
data class GenresData(val id: Long, val name: String, val count: Int) {
}
获取艺术家
/*** 获取艺术家* @param context*/fun getArtistsForCursor(context: Context): List<ArtistData> {val artistSortOrder = PreferencesUtility.getInstance(context).artistSortOrderval cursor: Cursor? = context.contentResolver.query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,arrayOf(DATA, ARTIST, NUMBER_ALBUM, NUMBER_TRACK),null,null,artistSortOrder)val arrayList: MutableList<ArtistData> = ArrayList()if (cursor != null && cursor.moveToFirst()) do {val artist = ArtistData(cursor.getLong(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3))arrayList.add(artist)} while (cursor.moveToNext())cursor?.close()return arrayList}
数据类
data class ArtistData(val id: Long, val name: String, val count: Int, val num: Int) {
}
完整代码
package com.zong.musiclib.helperimport android.annotation.SuppressLint
import android.content.ContentResolver
import android.content.Context
import android.database.Cursor
import android.provider.MediaStore
import com.zong.musiclib.utils.PreferencesUtilityobject MusicHelper {private const val DATA = "_id"private const val ARTIST = "artist"private const val NUMBER_ALBUM = "number_of_albums"private const val NUMBER_TRACK = "number_of_tracks"@SuppressLint("Range")fun getMusic(context: Context): MutableList<MusicData> {var songNumber = 0val songsList: MutableList<MusicData> = ArrayList() //用于装歌曲数据val contentResolver: ContentResolver = context.contentResolvervar cursor: Cursor? = nulltry {cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null, null, null);if (cursor != null) {while (cursor.moveToNext()) {//是否是音频val isMusic =cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC))//时长val duration =cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))//是音乐并且时长大于30秒if (isMusic != 0 && duration >= 30 * 1000) {//歌名val title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE))//歌手val artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));//专辑idval albumId =cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))//文件路径val dataPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA))val data: String =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DATA))val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID))val music = MusicData(id, -1, albumId, title, artist, "", data, duration, songNumber, dataPath)songsList.add(music)songNumber++}}}} catch (e: Exception) {e.printStackTrace();} finally {cursor?.close()}return songsList}/*** 获取所有流派** @param context* @return*/@SuppressLint("Range")fun getGenres(context: Context): List<GenresData?> {val cursor = context.contentResolver.query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, null, null, null, null)var genresList: MutableList<GenresData?> = ArrayList()if (cursor != null) {genresList = java.util.ArrayList(cursor.count)while (cursor.moveToNext()) {val id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Genres._ID))val name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Genres.NAME))genresList.add(GenresData(id, name))}cursor.close()}return genresList}/*** 获取艺术家* @param context*/fun getArtistsForCursor(context: Context): List<ArtistData> {val artistSortOrder = PreferencesUtility.getInstance(context).artistSortOrderval cursor: Cursor? = context.contentResolver.query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,arrayOf(DATA, ARTIST, NUMBER_ALBUM, NUMBER_TRACK),null,null,artistSortOrder)val arrayList: MutableList<ArtistData> = ArrayList()if (cursor != null && cursor.moveToFirst()) do {val artist = ArtistData(cursor.getLong(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3))arrayList.add(artist)} while (cursor.moveToNext())cursor?.close()return arrayList}}
相关文章:

android 使用MediaPlayer实现音乐播放--获取音乐数据
前面已经添加了权限,有权限后可以去数据库读取音乐文件,一般可以获取全部音乐、专辑、歌手、流派等。 1. 获取全部音乐数据 class MusicHelper {companion object {SuppressLint("Range")fun getMusic(context: Context): MutableList<Mu…...

.net 8使用hangfire实现库存同步任务
C# 使用HangFire 第一章:.net Framework 4.6 WebAPI 使用Hangfire 第二章:net 8使用hangfire实现库存同步任务 文章目录 C# 使用HangFire前言项目源码一、项目架构二、项目服务介绍HangFire服务结构解析HangfireCollectionExtensions 类ModelHangfireSettingsHttpAuthInfoUs…...
第 22 章 - Go语言 测试与基准测试
在Go语言中,测试是一个非常重要的部分,它帮助开发者确保代码的正确性、性能以及可维护性。Go语言提供了一套标准的测试工具,这些工具可以帮助开发者编写单元测试、表达式测试(通常也是指单元测试中的断言)、基准测试等…...

VB.Net笔记-更新ing
目录 1.1 设置默认VS的开发环境为VB.NET(2024/11/18) 1.2 新建一个“Hello,world”的窗体(2024/11/18) 1.3 计算圆面积的小程序(2024/11/18) 显示/隐式 声明 (2024/11/18&…...

centos 服务器 docker 使用代理
宿主机使用代理 在宿主机的全局配置文件中添加代理信息 vim /etc/profile export http_proxyhttp://127.0.0.1:7897 export https_proxyhttp://127.0.0.1:7897 export no_proxy"localhost,127.0.0.1,::1,172.171.0.0" docker 命令使用代理 例如我想在使用使用 do…...
python语言基础
1. 基础语法 Q: Python 中的变量与数据类型有哪些? A: Python 支持多种数据类型,包括数字(整数 int、浮点数 float、复数 complex)、字符串 str、列表 list、元组 tuple、字典 dict 和集合 set。每种数据类型都有其特定的用途和…...
Python中的Apriori库详解
文章目录 Python中的Apriori库详解一、引言二、Apriori算法原理与Python实现1、Apriori算法原理2、Python实现1.1、数据准备1.2、转换数据1.3、计算频繁项集1.4、提取关联规则 三、案例分析1、导入必要的库2、准备数据集3、数据预处理4、应用Apriori算法5、生成关联规则6、打印…...
MongoDB比较查询操作符中英对照表及实例详解
mongodb比较查询操作符中英表格一览表 NameDescription功能$eqMatches values that are equal to a specified value.匹配值等于指定值。$gtMatches values that are greater than a specified value.匹配值大于指定值。$gteMatches values that are greater than or equal to…...

掌上单片机实验室 – RT-Thread + ROS2 初探(25)
在初步尝试RT-Thread之后,一直在琢磨如何进一步感受它的优点,因为前面只是用了它的内核,感觉和FreeRTOS、uCOS等RTOS差别不大,至于它们性能、可靠性上的差异,在这种学习性的程序中,很难有所察觉。 RT-Threa…...
Kotlin中的?.和!!主要区别
目录 1、?.和!!介绍 2、使用场景和最佳实践 3、代码示例和解释 1、?.和!!介绍 Kotlin中的?.和!!主要区别在于它们对空指针的处理方式。 ?.(安全调用操作符):当变量可能为null时,使用?.可以安全地调用其方法或属性…...

iframe嵌入踩坑记录
iframe嵌入父子页面token问题 背景介绍 最近在做在平台A中嵌入平台B某个页面的需求,我负责的是平台B这边,使这个页面被嵌入后能正常使用。两个平台都实现了单点登录。 其实这是第二次做这个功能了,原本以为会很顺利,但没想到折腾…...
面试小札:Java的类加载过程和类加载机制。
Java类加载过程 加载(Loading) 这是类加载过程的第一个阶段。在这个阶段,Java虚拟机(JVM)主要完成三件事: 通过类的全限定名来获取定义此类的二进制字节流。这可以从多种来源获取,如本地文件系…...
Spring 上下文对象
1. Spring 上下文对象概述 Spring 上下文对象(ApplicationContext)是 Spring 框架的核心接口之一,它扩展了 BeanFactory 接口,提供了更多企业级应用所需的功能。ApplicationContext 不仅可以管理 Bean 的生命周期和配置࿰…...

Wireshark抓取HTTPS流量技巧
一、工具准备 首先安装wireshark工具,官方链接:Wireshark Go Deep 二、环境变量配置 TLS 加密的核心是会话密钥。这些密钥由客户端和服务器协商生成,用于对通信流量进行对称加密。如果能通过 SSL/TLS 日志文件(例如包含密钥的…...

测试人员--如何区分前端BUG和后端BUG
在软件测试中,发现一个BUG并不算难,但准确定位它的来源却常常让测试人员头疼。是前端页面的问题?还是后台服务的异常?如果搞错了方向,开发人员之间的沟通效率会大大降低,甚至导致问题久拖不决。 那么&#…...

【Vue】指令扩充(指令修饰符、样式绑定)
目录 指令修饰符 按键修饰符 事件修饰符 双向绑定指令修饰符 输入框 表单域 下拉框 单选按钮 复选框 样式绑定 分类 绑定class 绑定style tab页切换示例 指令修饰符 作用 借助指令修饰符,可以让指令的功能更强大 分类 按键修饰符:用来…...
Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0
firefly 公司出的rk3588的设备,其中已经安装了gcc 交叉编译工具,系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…...

HTML常用表格与标签
一、table表格标签: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <!--有大小为1的边框--> <table border"1">…...

网络安全与加密
1.Base64简单说明描述:Base64可以成为密码学的基石,非常重要。特点:可以将任意的二进制数据进行Base64编码结果:所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符:A~Z a~z 0~9 / 对文件进行base64编码…...
MySQL数据库-索引的介绍和使用
目录 MySQL数据库-索引1.索引介绍2.索引分类3.创建索引3.1 唯一索引3.2 普通索引3.3 组合索引3.4 全文索引 4.索引使用5.查看索引6.删除索引7.索引总结7.1 优点7.2 缺点7.3 索引使用注意事项 MySQL数据库-索引 数据库是用来存储数据,在互联网应用中,数据…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...

【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...