当前位置: 首页 > news >正文

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实现音乐播放--获取音乐数据

前面已经添加了权限&#xff0c;有权限后可以去数据库读取音乐文件&#xff0c;一般可以获取全部音乐、专辑、歌手、流派等。 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语言中&#xff0c;测试是一个非常重要的部分&#xff0c;它帮助开发者确保代码的正确性、性能以及可维护性。Go语言提供了一套标准的测试工具&#xff0c;这些工具可以帮助开发者编写单元测试、表达式测试&#xff08;通常也是指单元测试中的断言&#xff09;、基准测试等…...

VB.Net笔记-更新ing

目录 1.1 设置默认VS的开发环境为VB.NET&#xff08;2024/11/18&#xff09; 1.2 新建一个“Hello&#xff0c;world”的窗体&#xff08;2024/11/18&#xff09; 1.3 计算圆面积的小程序&#xff08;2024/11/18&#xff09; 显示/隐式 声明 &#xff08;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 中的变量与数据类型有哪些&#xff1f; A: Python 支持多种数据类型&#xff0c;包括数字&#xff08;整数 int、浮点数 float、复数 complex&#xff09;、字符串 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之后&#xff0c;一直在琢磨如何进一步感受它的优点&#xff0c;因为前面只是用了它的内核&#xff0c;感觉和FreeRTOS、uCOS等RTOS差别不大&#xff0c;至于它们性能、可靠性上的差异&#xff0c;在这种学习性的程序中&#xff0c;很难有所察觉。 RT-Threa…...

‌Kotlin中的?.和!!主要区别

目录 1、?.和!!介绍 2、使用场景和最佳实践 3、代码示例和解释 1、?.和!!介绍 ‌Kotlin中的?.和!!主要区别在于它们对空指针的处理方式。‌ ‌?.&#xff08;安全调用操作符&#xff09;‌&#xff1a;当变量可能为null时&#xff0c;使用?.可以安全地调用其方法或属性…...

iframe嵌入踩坑记录

iframe嵌入父子页面token问题 背景介绍 最近在做在平台A中嵌入平台B某个页面的需求&#xff0c;我负责的是平台B这边&#xff0c;使这个页面被嵌入后能正常使用。两个平台都实现了单点登录。 其实这是第二次做这个功能了&#xff0c;原本以为会很顺利&#xff0c;但没想到折腾…...

面试小札:Java的类加载过程和类加载机制。

Java类加载过程 加载&#xff08;Loading&#xff09; 这是类加载过程的第一个阶段。在这个阶段&#xff0c;Java虚拟机&#xff08;JVM&#xff09;主要完成三件事&#xff1a; 通过类的全限定名来获取定义此类的二进制字节流。这可以从多种来源获取&#xff0c;如本地文件系…...

Spring 上下文对象

1. Spring 上下文对象概述 Spring 上下文对象&#xff08;ApplicationContext&#xff09;是 Spring 框架的核心接口之一&#xff0c;它扩展了 BeanFactory 接口&#xff0c;提供了更多企业级应用所需的功能。ApplicationContext 不仅可以管理 Bean 的生命周期和配置&#xff0…...

Wireshark抓取HTTPS流量技巧

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

测试人员--如何区分前端BUG和后端BUG

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

【Vue】指令扩充(指令修饰符、样式绑定)

目录 指令修饰符 按键修饰符 事件修饰符 双向绑定指令修饰符 输入框 表单域 下拉框 单选按钮 复选框 样式绑定 分类 绑定class 绑定style tab页切换示例 指令修饰符 作用 借助指令修饰符&#xff0c;可以让指令的功能更强大 分类 按键修饰符&#xff1a;用来…...

Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0

firefly 公司出的rk3588的设备&#xff0c;其中已经安装了gcc 交叉编译工具&#xff0c;系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…...

HTML常用表格与标签

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

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;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数据库-索引 数据库是用来存储数据&#xff0c;在互联网应用中&#xff0c;数据…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 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)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

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配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...

【若依】框架项目部署笔记

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