首页 理论教育 打造一款简便易用的音乐播放器

打造一款简便易用的音乐播放器

时间:2023-06-30 理论教育 版权反馈
【摘要】:表4.1AssetManager类提供的常用方法5.使用MediaPlayer播放音视频MediaPlayer用于实现音视频播放功能,提供了播放音视频所需要的所有基础API。使用MediaPlayer对音乐进行播放或停止等操作,主要由表4.2所示的方法完成。实验中使用自定义适配器的List View展现歌曲列表,点击歌曲后将使用隐式启动方式启动服务,服务在后台播放选中的音乐。

打造一款简便易用的音乐播放器

1.实验目的

(1)熟悉隐式启动Service的方法。

(2)掌握List View使用自定义适配器的方法,了解List View动态更新的方法,了解自定义List View选项中控件触发事件的实现。

(3)掌握assets目录的特点和使用方法。

(4)熟悉使用MediaPlayer播放音乐的方式。

(5)掌握Alert Dialog的使用方法。

(6)了解LayoutInflator的使用方法。

2.Service

Service作为Android四大组件之一,是一个可以在后台执行长时间运行,并且没有用户界面的应用组件。例如,用户一边与某个应用程序的界面进行交互,一边使用该应用程序听音乐时,播放音乐就可以使用Service来实现。Service有两种使用方式:启动方式和绑定方式。

•启动方式:启动方式不能获取服务的实例,需要Service具有自管理功能。启动方式分为显式启动和隐式启动,隐式启动通过在Android Manifest.xml文件中为Service配置动作,供调用者调用,调用者无须Service类名即可启动Service。如果服务和调用服务的组件在不同的应用程序中,只能使用隐式启动方式。启动方式通过startService()启动服务,通过stopService()停止服务。实现Service的类必须继承自Service,启动方式调用Service的生命周期调用顺序如图4.1所示。

图4.1 Service启动方式的全生命周期

•绑定方式:绑定方式可以获取Service的对象实例,通过bindService()建立服务链接,通过unbindService()停止服务。绑定方式调用Service的生命周期调用顺序如图4.2所示。

图4.2 Service绑定方式的全生命周期

Service有一个最小代码集,不管是在启动方式下还是在绑定方式下都必须实现该方法,如下所示。

3.List View自定义适配器

第2章实验5中对List View的各种适配器做过介绍,其中自定义的适配器最复杂,也最灵活。使用自定义的适配器需要继承自Base Adapter,并覆盖4个方法,如下所示。

4.assets目录访问

assets目录一般用于存放较大的音频、视频文件,该目录和java、res目录是平级目录,该目录中文件的主要特点如下。

(1)assets目录下的文件在打包后会原封不动地保存在APK包中,不会被编译成二进制文件。

(2)assets目录下的文件不会被映射到R.java中,因此在代码中引用该目录下的资源时不能通过R.资源目录.资源名称的方式访问,访问时需要通过get Assets()方法获取Asset Manager对象,再根据Asset Manager获取文件描述。Asset Manager类提供的常用方法如表4.1所示。

表4.1 AssetManager类提供的常用方法

5.使用MediaPlayer播放音视频

MediaPlayer用于实现音视频播放功能,提供了播放音视频所需要的所有基础API。使用MediaPlayer对音乐进行播放或停止等操作,主要由表4.2所示的方法完成。

表4.2 MediaPlayer类常用方法

续表

6.AlertDialog的使用

Alert Dialog是常用的对话框控件,本实验中用于显示点击按钮后弹出的对话框。通常用Alert Dialog.Builder(Context)创建带两个按钮的对话框,Alert Dialog.Builder常用的方法如表4.3所示。

表4.3 AlertDialog.Builder常用的方法

7.LayoutInflater的使用

LayoutInflater类可以获取布局填充器,可以在布局中填充另一个视图,在实际开发中是常用的一个类。LayoutInflater会查找layout目录下的XML布局文件,并且实例化该布局。本实验中用到的核心代码如下所示。

8.实验界面与功能

本实验实现的是简单的音乐播放器。实验中使用自定义适配器的List View展现歌曲列表,点击歌曲后将使用隐式启动方式启动服务,服务在后台播放选中的音乐。其功能的详细描述如下。

(1)打开应用程序出现图4.3(a)所示的界面,点击任意一首歌曲,程序开始调用MediaPlayer播放该歌曲,同时播放图标变成暂停图标,上方的图片上出现一个暂停按钮,如图4.3(b)所示。

(2)点击正在播放的歌曲可以停止播放,或者点击其他歌曲停止播放当前歌曲,转而播放点击的歌曲。

(3)点击图4.3(a)所示的界面中的“…”,弹出AlertDialog显示歌曲的详细信息,如图4.3(c)所示。

图4.3 实验界面与功能

9.模块结构

图4.4所示为本实验的目录结构,本实验有4个Java类、一个存放了歌曲的assets目录和mipmap目录下的5张图片,4个Java类的作用如下所示。

(1)Main Activity:主入口类,是本实验的主界面。它对应的布局文件是main_activity.xml文件,该文件中定义了3个控件,包括两个重叠的Image View,其中一个是界面上方的背景大图,一个是上方的暂停按钮,还有一个控件是List View。该类在onCreate()方法中对控件进行初始化,为List View适配数据和设置监听器。适配数据时用到的数据是通过get Data()方法获取的。监听器中播放音乐是通过start Player()方法实现的,该方法通过启动服务播放音乐,停止播放音乐是通过stop Player()方法实现的,该方法通过停止服务停止播放音乐。Main Activity代码结构如图4.5所示。

图4.4 App09工程目录结构

(2)MusicService:是一个播放音乐的服务类,该类继承自Service。本实验通过隐式启动方式启动服务,所以须实现启动服务的生命周期回调函数onStartCommand()方法、结束服务的生命周期回调函数onDestroy()方法以及Service的最小代码集onBind()方法。其中,在onStartCommand()方法中调用了MediaPlayer播放音乐,在onDestroy()方法中调用该类终止音乐的播放。MusicService代码结构如图4.6所示。

图4.5 Main Activity代码结构

图4.6 MusicService代码结构

(3)Bean:用于存放适配器中要适配的4个控件,这4个控件的布局文件为listitem.xml。

(4)List View Adapter:自定义的适配器类,用于适配List View中一个选项的(或者一行)数据,一行数据的布局是listitem.xml文件。该适配器在Main Activity中实例化,实例化时所用到的入参将是要适配的数据,系统根据布局文件listitem.xml适配到Main Activity中的List View上。该类继承了Base Adapter类,实现了OnClick Listener接口,所以实现了Adapter必须要实现的4个方法,以及实现OnClick Listener接口时必须实现的onClick()方法。自定义的适配器类结构如图4.7所示。

10.实验步骤

步骤1:新建模块App09,Java代码类名和布局文件名保持默认。

步骤2:修改values/colors.xml文件,将color Accent的取值修改成状态栏colorPrimaryDark的颜色,color Accent是一般控件被选中时默认采用的颜色。(www.xing528.com)

图4.7 自定义的适配器类结构

步骤3:创建assets目录。右击工程,选择“New”|“Folder”|“Assets Folder”,如图4.8所示,并且复制3个MP3文件至该目录下。

图4.8 新建assets目录

步骤4:复制图片文件至mipmap目录下。

步骤5:修改activity_main.xml文件,删除该文件自带的控件Text View,参考图4.3(a)向该文件中拖入两个Image View和一个List View,并设置好每个控件的位置约束。

步骤6:右击res/layout目录,在弹出的菜单中依次选择“New”|“layout resources file”,在弹出的对话框中输入文件名“listitem”。在该布局文件中放入两个Image View和一个线性布局,在线性布局中放入两个Text View,该布局文件的Component Tree如图4.9所示。

图4.9 listitem.xml的Component Tree

步骤7:右击java目录下的包路径,选择“New”|“Java Class”新建一个类,类名为Bean,该类中仅包含布局文件listitem.xml中控件的定义,用于适配4个控件到Activity,即List View中的一行所使用的控件,如下所示。

步骤8:新建一个Java类,类名为List View Adapter,该类继承自Base Adapter,并且实现了OnClick Listener接口。

步骤9:在Main Activity.java文件中获取在布局文件中定义的ImageView和List View。为List View增加步骤8中定义的适配器。为List View增加监听器,当List View的内容被点击时调用MusicService播放选中的音乐,如果再次被点击则调用MusicService停止播放该音乐,如果当前音乐正在播放时,用户点击了另一首音乐,则先停止正在播放的音乐,再播放新选中的音乐。最后实现步骤8中调用的click()方法。

步骤10:新建MusicService类,该类继承自Service,在该Service的onStartCommand()方法中播放音乐,在stopService()方法中停止播放音乐。

步骤11:修改Android Manifest.xml文件,在application……/标签中注册MusicService,并且为该Service设置动作。

步骤12:运行并测试App09。

知识拓展:绑定方式

本实验主要介绍了用启动方式启动服务播放音乐,该功能不能实现音乐播放进度显示、进度控制,因为在Main Activity中没有获取MediaPlayer实例。可以通过以下两种方式获取MediaPlayer实例。

方法1:将MediaPlayer对象定义为静态的(static),再定义一个静态的方法获取该对象,那么需要在MusicService中增加如下代码。

修改Main Activity获取MediaPlayer实例,并通过调用MediaPlayer的方法实现对音乐的控制和对信息的获取。

方法2:通过绑定方式获取MusicService的实例,通过MusicService的实例获取MediaPlayer实例。

目前应用市场上主要的播放器均可实现对音乐的各种操作,例如,图4.10所示的界面实现了控制音乐播放的功能,下面以方法2为例在原实验的基础上更改代码,实现图片展示的效果。

步骤1:新建模块App10。在界面中放入Seek Bar用于控制进度,放入一个Text View用于显示播放时间,两个控件默认设置为“INVISIBLE”。在Main Activity的onCreate()方法中通过find View ById()方法获取这两个控件。

图4.10 带进度控制的播放器

步骤2:定义变量ServiceConnection用于获取MusicService实例,该变量也是使用Service绑定方式必须定义的参数。ServiceConnection是一个接口类,该对象须在Main Activity.java文件中获取,要实例化该类必须实现两个方法:onServiceDisconnected()和onServiceConnected()。其中,onServiceConnected()方法的第一个参数可以获取服务的实例,当服务建立连接后会调用该方法,一旦调用服务就会通过MusicService启动音乐,并通过Handler通知界面定时更新Seek Bar。

步骤3:在onCreate()方法中实现SeekBar的监听事件,主要包括进度条的拖动和进度的显示。进度条的进度取值范围为[0,100],在拖动进度条后获取进度条的百分比取值,设置MediaPlayer播放对应时间点的音乐。Handler每100毫秒通知Seek Bar更新,当Seek Bar更新后设置Text View更新播放的进度。

步骤4:定义Handler,在接收到子线程发来的消息后,获取MediaPlayer当前播放时间和总时长,计算出对应的Seek Bar的进度,并更新SeekBar。

步骤5:更改服务启动和停止方式,并在启动时设置Seek Bar和Text View可见,在解除服务绑定时设置Seek Bar和Text View不可见。

步骤6:通过绑定方式实现MusicService,在该类中增加get MediaPlayer()方法并返回mediaPlayer。

步骤7:修改Android Manifest.xml中注册的服务。

思考

(1)如何增加上一首、下一首按钮并实现其功能?单曲循环、列表循环如何实现?

(2)如何为每首歌曲前的ImageView增加监听事件?

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈