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

Kotlin实现简单音乐播放器

关于音乐播放器,我真的是接触比较多,听歌作为我第一大爱好,之前也用Java设计过音乐播放器,感兴趣的同学可以阅读:Android Studio如何实现音乐播放器(简单易上手)和 Android Studio实现音乐播放器2.0

一、实验目的

理论知识

  1. 掌握Kotlin面向对象的软件开发方面的基础知识。
  2. 巩固前期Activity、UI控件的使用。
  3. 掌握Service和BroadcastReceiver的特点及用法。

专业技能

  1. 熟悉Android软件开发环境并掌握具体的工具的使用。
  2. 掌握Service和BroadcastReceiver组件的使用。
  3. 掌握移动应用软件分析和设计方法,并能将其运用到工程实践当中。

职业素养

  1. 逐步形成系统的设计的思想,具有一定的创新精神。
  2. 养成良好的编程习惯。

二、实验内容

根据Service及BroadcastReceiver的知识讲解和案例使用,实现一个Android音乐播放器,强化对服务与广播的理解。要求能实现音乐的播放,暂停,上一首,下一首等功能。要求:

  1. 巩固Android应用开发工具(Eclipse或者Android Studio)的常规用法;
  2. 巩固Activity、UI控件的常规用法;
  3. 掌握Service和BroadcastReceiver的编程要点;
  4. 理解MediaPlayer的使用。

三、实验步骤

1、页面布局

先考虑下简单音乐播放器的元素,那肯定是播放暂停停止,上一首和下一首了。

在这里插入图片描述

父布局是RelativeLayout,然后是ListView显示歌单,接下去就是Button按键了,没什么需要讲的,都过于基础。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ListViewandroid:id="@+id/lv_music"android:layout_width="match_parent"android:layout_height="500dp"/><LinearLayoutandroid:id="@+id/ll_play"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_below="@+id/lv_music"android:layout_marginTop="20dp"><Buttonandroid:id="@+id/btn_start"android:layout_width="0dp"android:layout_weight="1"android:text="开始播放"android:textSize="20sp"android:gravity="center"android:layout_margin="5dp"android:background="@drawable/btn_selector"android:layout_height="match_parent"/><Buttonandroid:id="@+id/btn_pause"android:layout_width="0dp"android:layout_weight="1"android:text="暂停播放"android:textSize="20sp"android:gravity="center"android:layout_margin="5dp"android:background="@drawable/btn_selector"android:layout_height="match_parent"/><Buttonandroid:id="@+id/btn_stop"android:layout_width="0dp"android:layout_weight="1"android:text="停止播放"android:textSize="20sp"android:gravity="center"android:layout_margin="5dp"android:background="@drawable/btn_selector"android:layout_height="match_parent"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_below="@+id/ll_play"android:layout_marginTop="20dp"><Buttonandroid:id="@+id/btn_pre"android:layout_width="0dp"android:layout_weight="1"android:text="上一首"android:textSize="20sp"android:gravity="center"android:layout_margin="5dp"android:background="@drawable/btn_selector"android:layout_height="match_parent"/><Buttonandroid:id="@+id/btn_next"android:layout_width="0dp"android:layout_weight="1"android:text="下一首"android:textSize="20sp"android:gravity="center"android:layout_margin="5dp"android:background="@drawable/btn_selector"android:layout_height="match_parent"/></LinearLayout></RelativeLayout>

2、音乐服务

其实播放音乐只需要MediaPlayer和start、resume等方法就行,几行代码解决。但Service越来越需要音乐播放器来体现出来,作为四大组件之一,Service从来不露脸,借助Activity来发挥自己的才能。是四大组件里面和Content Provider一样低调的人。

首先定义mediaPlayer对象。然后重写 onCreate()方法,在里面给mediaPlayer初始化和initMediaPlayer(),init的方法中就是打开assets文件夹下的音乐,调用setDataSource()设置数据源,然后prepare()准备就绪。

    private lateinit var mediaPlayer:MediaPlayerprivate var index = 0override fun onCreate() {super.onCreate()mediaPlayer = MediaPlayer()initMediaPlayer()}
    fun initMediaPlayer() {val assetManager = assetsvar fileName = "music" + index + ".mp3"var fd = assetManager.openFd(fileName)mediaPlayer.setDataSource(fd.fileDescriptor, fd.startOffset, fd.length)mediaPlayer.prepare()}

既然要通过Service实现音乐服务,那么就要控制音乐播放,在MusicService类中定义一个内部类MusicControl。它继承自Binder,里面只有成员方法,而且都没有返回值,其实就是对mediaplaer的方法进行了封装。start()、pause()、reset(),全局变量index是歌曲下标,在切换上下首时调用。

inner class MusicControl:Binder() {fun playMusic() {if (!mediaPlayer.isPlaying) {mediaPlayer.start()}}fun pasueMusic() {if (mediaPlayer.isPlaying) {mediaPlayer.pause()}}fun stopMusic() {if (mediaPlayer.isPlaying) {mediaPlayer.reset()initMediaPlayer()}}fun prePlay() {// 循环播放前一首index = (index + 5) % 6// 如果正在播放则重置播放器if (mediaPlayer.isPlaying) {mediaPlayer.reset()}initMediaPlayer()mediaPlayer.start()}fun nextPlay() {// 循环播放下一首index = (index + 7) % 6// 如果正在播放则重置播放器if (mediaPlayer.isPlaying) {mediaPlayer.reset()}initMediaPlayer()mediaPlayer.start()}}

3、音乐播放

创建适配器,使用默认的simple_list_item_1,显示一行歌曲名就行。如果你想自定义加上其他的歌曲元素,可以自己创建一个适配器和子项布局文件。这里讲解的重点是Service和Activity进行绑定。

    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, musicList)binding.lvMusic.adapter = adapter// 定义意图对象,绑定服务自动创建musicIntent = Intent(this, MusicService::class.java)bindService(musicIntent, musicConnection, BIND_AUTO_CREATE)initView()}

首先MainActivity里面还需要定义个内部类MusicConnection,用于连接MusicService的内部类,继承自ServiceConnection,重写的分类方法中只是在连接上服务的时候将iBinder赋值给musicControl。这里musicControl就是MusicService的内部类对应的对象。

lateinit var musicControl:MusicService.MusicControl
    inner class MusicConnection:ServiceConnection {override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {musicControl = p1 as MusicService.MusicControl}override fun onServiceDisconnected(p0: ComponentName?) {}}

下面我们就用初始化好的MusicConnection对象来连接MainActivity和MusicService。很简单的两句就好了。

    musicIntent = Intent(this, MusicService::class.java)bindService(musicIntent, musicConnection, BIND_AUTO_CREATE)

下面我们设置下按钮的点击事件,其实就是直接调用musicControl对象的方法。

	override fun onClick(p0: View?) {when(p0?.id) {R.id.btn_start->{musicControl.playMusic()}R.id.btn_pause->{musicControl.pasueMusic()}R.id.btn_stop->{musicControl.stopMusic()}R.id.btn_pre->{musicControl.prePlay()}R.id.btn_next->{musicControl.nextPlay()}}}

四、运行演示

打开就是主页面,点击开始播放,从第一首开始,然后可以暂停播放,再点开始播放就是继续播放,随时停止播放,上一首和下一首也无比流畅。

在这里插入图片描述

五、实验总结

这已经是第四次做音乐播放器了,这次做的也是最快的,也可能是简单的原因,没加什么复杂内容,其实如果是从音乐文件的数据库中读取再播放,我觉得就要花些时间了。或者从SD卡中读文件也是不错的想法,感兴趣的同学可以尝试挑战。

🔥源代码已上传CSDN🔥

相关文章:

Kotlin实现简单音乐播放器

关于音乐播放器&#xff0c;我真的是接触比较多&#xff0c;听歌作为我第一大爱好&#xff0c;之前也用Java设计过音乐播放器&#xff0c;感兴趣的同学可以阅读&#xff1a;Android Studio如何实现音乐播放器&#xff08;简单易上手&#xff09;和 Android Studio实现音乐播放器…...

ShardingSphere-Proxy 数据库协议交互解读

数据库协议对于大部分开发者来说算是比较冷门的知识&#xff0c;一般的用户、开发者都是通过现成的数据库客户端、驱动使用数据库&#xff0c;不会直接操作数据库协议。不过&#xff0c;对数据库协议的特点与流程有一些基本的了解&#xff0c;有助于开发者在排查数据库功能、性…...

基于ubuntu20.4的wine的MDK5软件的安装

本文基于ubuntu20.4安装MDK5的keil软件&#xff0c;由于MDK不提供linux版本的安装软件&#xff0c;因此需要利用wine软件来安装MDK5软件&#xff0c;具体流程包括wine软件安装、MDK5安装及MDK5的lic添加等3部分内容。具体流程如下所示&#xff1a; &#xff08;一&#xff09;…...

Jmeter之直连数据库框架搭建简介

案例简介 通过直连数据库让程序代替接口访问数据库&#xff0c;如果二者预期结果不一致&#xff0c;就找到了程序的缺陷。 下面通过一个案例分析讲解如何实现&#xff1a;获取某个字段值&#xff0c;放在百度上搜索。 实现方式 1、Jmeter本身不具备直连数据库的功能&#xf…...

备战蓝桥杯【高精度乘法和高精度除法】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

火眼审阅 | 基于NLP和OCR识别技术赋能合同审阅

合同作为确定权利义务的法律文件&#xff0c;贯穿企业内外部活动的所有环节&#xff0c;可见合同数据之于企业是非常重要的数据资产。 合同管理是企业营业中的重要部分&#xff0c;其中合同审核是企业法务的基本工作之一。而对于所有的法务人员一直存在一个问题&#xff1a;合…...

关于在集合中对象比较属性值的问题

关于在集合中对象比较属性值的问题1 问题说明2 问题排查3 总结及伪代码楼主在最近遇到一个场景&#xff0c;项目中有一个校验。 需要将数据库查询的集合对象与前端传递的集合对象进行比较&#xff0c;看数据是否被修改。 1 问题说明 基于上面项目需求&#xff0c;项目为较老的…...

java微信小程序旅游管理系统

本旅游服务软件,主要实现了管理员后端&#xff1a;首页、个人中心、旅游攻略管理、旅游资讯管理、景点信息管理、门票预定管理、用户管理、酒店信息管理、酒店预定管理、推荐路线管理、论坛管理、系统管理,用户前端&#xff1a;首页、景点信息、酒店信息、论坛中心、我的等。总…...

2023年要跟踪的11个销售管理关键指标

销售管理关键指标有&#xff1a;营销合格线索数量&#xff08;MQL&#xff09;、MQL 到 SQL 的转换率、商机赢单率、获客成本、总销售额、客户终身价值&#xff08;LTV&#xff09;、LTV 与 CAC 比率、赢单周期、每客户平均销售额&#xff08;平均客单价&#xff09;、每销售人…...

MongoDB--》基本常用命令使用

目录 数据库操作命令 选择和创建数据库 数据库的删除 集合操作命令 集合的显示创建 集合的隐式创建 集合的删除 文档基本的CRUD&#xff08;增删改查&#xff09; 文档的插入 文档的基本查询 文档的更新 删除文档 数据库操作命令 数据库常用的操作命令如下&#x…...

js浮点数四则运算精度丢失以及toFixed()精度丢失解决方法

js浮点数四则运算精度丢失以及tofixed精度丢失解决方法一、js浮点数计算精度丢失的一些例子1、四则运算精度丢失&#xff1a;2、toFixed() 四舍五入精度丢失&#xff1a;二、浮点数计算精度丢失的原因三、解决办法1、使用 big.js&#xff08;如果有大量连续的计算推荐使用&…...

高姿态下的面部表情识别系统

效果展示&#xff1a; python表情、性别识别面部表情识别 (FER) 在计算机安全、神经科学、心理学和工程学方面有大量应用。由于其非侵入性&#xff0c;它被认为是打击犯罪的有用技术。然而&#xff0c;FER 面临着几个挑战&#xff0c;其中最严重的是它在严重的头部姿势下的预测…...

English Learning - Day59 作业打卡 2023.2.13 周一

English Learning - Day59 作业打卡 2023.2.13 周一引言1. 我有一些急事要处理。2. 这个孩子无忧无虑。3. 那个骑在白马上的姑娘是我姐姐。4. 对方正在给我们公司施加压力迫使我们降价。5. 我的医生告诉我要少吃垃圾食品。6. 我从来不熬夜。7.我早就想跟你聊一聊了。8.我一定不…...

图机器学习

图机器学习1、图机器学习导论1.1图神经网络与普通神经网络的异同2、图的基本表示和特征工程2.1 图的基本表示2.1.1 图的本体设计2.1.2 图的种类2.1.3节点连接数&#xff08;度&#xff09;2.1.4图的基本表示&#xff08;邻接矩阵&#xff09;节点数量少使用2.1.5图的基本表示&a…...

ArcGIS中ArcMap创建渔网Create Fishnet:生成指定大小的格网矢量文件

本文介绍在ArcMap软件中&#xff0c;通过“Create Fishnet”工具创建渔网&#xff0c;从而获得指定大小的矢量格网数据的方法。 首先&#xff0c;我们在创建渔网前&#xff0c;需要指定渔网覆盖的范围。这里我们就以四川省为例&#xff0c;在这一范围内创建渔网&#xff1b;其中…...

TensorRT中的自定义层

TensorRT中的自定义层 文章目录TensorRT中的自定义层9.1. Adding Custom Layers Using The C API9.1.1. Example: Adding A Custom Layer With Dynamic Shape Support Using C重要提示&#xff1a;覆盖检查索引小于pos的连接的格式/类型&#xff0c;但绝不能检查索引大于pos的连…...

部署智能合约到公链

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…...

Windows server——部署DNS服务(3)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.管理DNS服务 1.子域 案例 2. 委派 案例 1&#xff09;添加主机记录 …...

9. QML_OpenGL--2. 在QQuick中搭建加载OpenGL框架

1. 说明&#xff1a; OPenGL一般在 QtWidget 中使用&#xff0c;但目前使用 QML 做界面开发是一种趋势&#xff0c;同时在QML中使用OPenGL进行渲染也是十分必要&#xff0c;文章简单介绍如何在QML中使用 OPenGL&#xff0c;搭建了一种基本的框架。整体思路和在 QtWidget 中类似…...

亚马逊云科技携手滴普科技,打造数据智能新标杆

随着企业数字化转型的不断深入&#xff0c;数据对于业务的价值和重要性也逐渐凸显。越来越多企业意识到&#xff0c;只有不断提升底层数据基础平台的性能和能力&#xff0c;才能构建数据驱动的业务&#xff0c;增强企业核心竞争力。作为湖仓一体数据智能基础软件独角兽企业&…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...