当前位置: 首页 > 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;增强企业核心竞争力。作为湖仓一体数据智能基础软件独角兽企业&…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...