音乐播放器
一,介绍一下这次的开发主题:
一个简易的音乐播放器(如果我能做出不简单的我就不简单了)
其中主要实现如下功能
- 播放和暂停
- 切歌(没有耳机切歌功能)
二, 设计流程
一,界面设计
其实也没设计啥,简单期间我就简单的加了三个线性布局,老师说要有的都有,老师不要求的都不要
首先author和title是不能少的,只是用TextView
来填写,设置一下参数就ok
然后去阿里巴巴的矢量库找几个图标
二,功能实现
现在还不可能实现在线播放所以还是要在本地加歌,在app文件下new一个assets文件夹
然后整几首歌进去,整,整大份的。
下面我们就要用到service
了,
Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行,Service基本上分为两种形式:启动状态,绑定状态
看起来似乎难以理解,其实主要内容主要是被Activity
调用然后还不会被Activity
的销毁而关闭
这也就是我们这次实现的难点
要进行音乐播放的话,我们需要使用一个叫MediaPlayer的类。播放音乐的步骤如下:
MediaPlayer mPlayer = new MediaPlayer();
// 歌曲文件名
String music = "promise.mp3";
// 获取附件管理器
AssetManager am = getAssets();;
// 打开指定音乐文件
AssetFileDescriptor afd = am.openFd(music);
mPlayer.reset();
// 使用MediaPlayer加载指定的声音文件。
mPlayer.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
// 准备声音
mPlayer.prepare();
// 播放
mPlayer.start();
然后新建一个service
类
然后就创建活动
public void onCreate() {
super.onCreate();
am = getAssets();
// 创建BroadcastReceiver
serviceReceiver = new MyReceiver();
// 创建IntentFilter
IntentFilter filter = new IntentFilter();
filter.addAction(MainActivity.CTL_ACTION);
registerReceiver(serviceReceiver, filter);
// 创建MediaPlayer
mPlayer = new MediaPlayer();
// 为MediaPlayer播放完成事件绑定监听器
mPlayer.setOnCompletionListener(new OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer mp) {
Log.d("musicService", "播放完成");
current++;
if (current >= 3) {
current = 0;
}
// 准备并播放音乐
prepareAndPlay(musics[current]);
//发送广播通知Activity更改文本框
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("current", current);
sendIntent.putExtra("currentTime", mPlayer.getCurrentPosition());
sendIntent.putExtra("totalTime", mPlayer.getDuration());
// 发送广播,将被Activity组件中的BroadcastReceiver接收到
sendBroadcast(sendIntent);
}
});
之后就可以设计一下广播通信
public void onReceive(final Context context, Intent intent) {
int control = intent.getIntExtra("control", -1);
Log.d("musicReceiver", "收到广播, control=" + control);
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();
if (current + 1 >= musics.length) {
current = 0;
} else {
current++;
}
prepareAndPlay(musics[current]);
status = 0x12;
break;
}
// 上一首
case 3:
if (status == 0x12 || status == 0x13) {
mPlayer.stop();
if (current - 1 < 0) {
current = musics.length - 1;
} else {
current--;
}
prepareAndPlay(musics[current]);
status = 0x12;
}
}
// 广播通知Activity更改图标、文本框
Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);
sendIntent.putExtra("update", status);
sendIntent.putExtra("current", current);
// 发送广播,将被Activity组件中的BroadcastReceiver接收到
sendBroadcast(sendIntent);
}
}
为了使广播能够接受到准确的定义,我们需要在activity里面加入两个定义
public static final String CTL_ACTION ="org.xr.action.CTL_ACTION";
public static final String UPDATE_ACTION = "org.xr.action.UPDATE_ACTION";
最后补充一下activity
switch (update) {
case 0x11:
play.setImageResource(R.drawable.play);
status = 0x11;
break;
// 控制系统进入播放状态
case 0x12:
// 播放状态下设置使用暂停图标
play.setImageResource(R.drawable.pause);
// 设置当前状态
status = 0x12;
break;
// 控制系统进入暂停状态
case 0x13:
// 暂停状态下设置使用播放图标
play.setImageResource(R.drawable.play);
// 设置当前状态
status = 0x13;
break;
}
}
}
@Override
public void onClick(View source) {
// 创建Intent
Intent intent = new Intent("org.xr.action.CTL_ACTION");
switch (source.getId()) {
// 按下播放/暂停按钮
case R.id.play:
intent.putExtra("control", 1);
break;
case R.id.last:
intent.putExtra("control", 3);
case R.id.next:
intent.putExtra("control", 2);
}
// 发送广播,将被Service组件中的BroadcastReceiver接收到
sendBroadcast(intent);
}
}
最后展示一下效果