主要功能
- 暂停,播放状态恢复
- 上一首下一首切换
- 播放列表复位
- 播放进度监听
- 音量监听
前言
Broadcast(广播机制) 是一种广泛运用的应用程序之间传输信息的机制,而 BroadcastReceiver(广播接收器) 则是用于接收来自系统和应用的广播对并对其进行响应的组件,Android中我们要发送的广播内容是一个Intent,这个Intent中可以携带我们要传送的数据。创建一个广播接收器非常简单,只需要继承 BroadcastReceiver,并重写onReceive()即可。BroadcastReceiver也是四大组件之一,所以我们也需要对BroadcastReceiver进行注册,不同于其他四大组件,BroadcastReceiver有两种注册方式,分别是静态注册和动态注册。
而之所以要用广播机制来制作手机音乐盒;是因为现在的都是在线音乐盒,在我们点击播放一首歌曲的时候,要从服务器拿数据,然后播放,这其实不止一个流程,可以理解为多线程的,普通的函数调用实现效果不好。而广播机制和Binder机制不一样的地方在于,广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。
音乐盒代码实现
布局文件
一个layout_update.xml文件。
xml文件我使用的是ableLayout布局。它拥有标记代表一行,它在布局里面相当于一个小容器。网格布局没有代表列的标记,列的实现是通过在行标记里面添加组件,每个组件占一列。这样可以使得音乐盒界面设置相对宽松,方便我进行音乐盒的简单布局。下面是布局设置的图片(每一行是一个TableRow,里面设置布局的各个组件,一个TableRow里放一个LinearLayout自适应image的高度)
MainActivity.java文件
这里要实现发送广播和接收音乐服务返回的广播,实现用户点击操作。
1、监听4个按钮的点击事件,发生点击事件就发送广播;
2、定义一个BroadcastReceiver监听从Service中传回的广播;
3、根据传回广播中携带的信息设置控制系统的状态,更改界面中播放键的图案显示和文本显示的歌曲信息。
具体信息请查看源码仓库 MusicService.java文件
MusicService.java文件
这里是音乐播放服务,在此实现播放音乐的逻辑。 其中实现播放、暂停和停止使用一个status记录当前状态实现效果。而实现上一首、下一首的功能时,首先实例代码中的assets文件夹里导入了三首歌曲,music数组中也只有着三组数据,使用current记录下标,而上一首、下一首的关键点在于越界,当current<=0和current>=3的情况,以上一首到达current=0时为例,设置current指向数组最后一项,即music.length-1。普通情况下点击上一首,current只需减一,然后播放当前current所指歌曲即可。下一首的实现类似,也就是current>=3的情况。由于可能随后会自己添加新的歌曲,所以使用current>=3并不能满足所有的情况,这时我就采用的是current >= musics.length 根据歌曲列表的长度来调整满足的条件,这样我们就可以自如添加歌曲而不用一直要修改代码了。
之后设置一个BroadcastReceiver,接收广播信息存在变量里;然后通过switch判断语句判断播放器的状态,实现暂停和播放。(上一首下一首判断语句很麻烦,调试前一点上一首就进入下一首的死循环;我调了好久才调好) 核心代码:
int control = intent.getIntExtra("control", -1);
switch (control) {
// 播放或暂停
case 1:
// 原来处于没有播放状态
if (status == 0x11) {
// 准备、并播放音乐
prepareAndPlay(musics[current]);
status = 0x12;
}
// 原来处于播放状态
else if (status == 0x12) {
// 暂停
mPlayer.pause();
// 改变为暂停状态
status = 0x13;
}
// 原来处于暂停状态
else if (status == 0x13) {
// 播放
mPlayer.start();
// 改变状态
status = 0x12;
}
break;
// 停止声音
case 2:
// 如果原来正在播放或暂停
if (status == 0x12 || status == 0x13) {
// 停止播放
mPlayer.stop();
status = 0x11;
}
break;
case 3:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==0) {
current=musics.length-1;
}
//准备并播放音乐
else {
current=current-1;
}
prepareAndPlay(musics[current]);
status=0x12;
}
//原来处于播放状态
else if (status==0x12)
{
//上一首//准备并播放音乐
if(current==0) {
current=musics.length-1;
}
else {
current=current-1;
}
prepareAndPlay(musics[current]);
}
break;
case 4:
//原来处于没有播放或暂停状态
if (status==0x11||status==0x13)
{
if(current==musics.length-1) {
current=0;
} //准备并播放音乐
else {
current=current+1;
}
prepareAndPlay(musics[current]);
status=0x12;
}
else if (status==0x12)
{
if(current==musics.length-1) {
current=0;
}
else {
current=current+1;
}
prepareAndPlay(musics[current]);
}
break;
}
更改了更新状态之后就要发送广播来改变播放器的图标:
// 发送广播通知Activity更改图标、文本框
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update", status);
sendIntent.putExtra("current", current);
// 发送广播 ,将被Activity组件中的BroadcastReceiver接收到
sendBroadcast(sendIntent);
我的音乐盒源码仓库:码云gitee.com/SDVA8766304…