当前位置: 首页 > 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;数据…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...