上一篇文章 Android音乐播放器 -- 实现框架 说到 MediaPlayer Service 就是音乐播放器的”中部枢纽“,为什么这样说,主要有两点
1. MediaPlayer Service (简称MPS ) 负责整个音乐播放器的协调一致,比如,在播放列表显示当前播放的歌曲和播放详情显示的内容必须一致,这个就需要MPS来协调
2. MPS肩负起音乐播放器最本质的工作 -- 播放音乐 , 使用MPS 进行音乐播放,就算播放器在后台运行,仍然可以继续播放。
MPS包含下面三个模块内容
1. 接收来自Activity的播放请求
@Override public int onStartCommand(Intent intent, int flag, int startId) { Log.e(TAG, "onStartCommand"); //判断当前播放列表类型 type0 = intent.getIntExtra("TYPE",-1); if(type0 == Common.PlayerType.TYPE_ALL) { musicInfos = CursorHandle.getMusicInfos(MediaPlayerService.this); type = type0; } else if(type0 == Common.PlayerType.TYPE_ALBUM ) { titleName = intent.getStringExtra("TitleName"); musicInfos = CursorHandle.getAlbumInfos(MediaPlayerService.this, titleName); type = type0; } else if(type0 == Common.PlayerType.TYPE_SINGER ) { titleName = intent.getStringExtra("TitleName"); musicInfos = CursorHandle.getArtistInfos(MediaPlayerService.this, titleName); type = type0; } path = intent.getStringExtra("url"); //歌曲路径 currentposition = intent.getIntExtra("listPosition", -1); //当前播放歌曲的在mp3Infos的位置 msg = intent.getIntExtra("MSG", 0); //播放信息 if (msg == Common.PlayerMsg.MSG_PLAY) { //点解列表 直接播放音乐 Intent sendIntent = new Intent(ACTION_UPDATE_INFO); isPlaying = true; sendIntent.putExtra("isPlaying", true); sendIntent.putExtra("currentposition", currentposition); sendIntent.putExtra("TYPE", type); sendIntent.putExtra("TitleName", titleName); // 发送广播,将被Activity组件中的BroadcastReceiver接收到 sendBroadcast(sendIntent); PlayMusic(0); } else if (msg == Common.PlayerMsg.MSG_PAUSE_RUSUME) { //暂停 PauseNResumeMusic(); } else if (msg == Common.PlayerMsg.MSG_PRIVIOUS) { //上一首 PreviousMusic(); } else if (msg == Common.PlayerMsg.MSG_NEXT) { //下一首 NextMusic(); } else if (msg == Common.PlayerMsg.MSG_CHANGE_PROGRESS) { //点击进度条 更新音乐服务 currentTime = intent.getIntExtra("progress", -1); mHandler.removeMessages(1); isPlaying = true; //更新UI 主要是为了解决暂停点击seekbar 后 play button UI没更新问题 Intent sendIntent = new Intent(ACTION_UPDATE_INFO); sendIntent.putExtra("isPlaying", isPlaying); sendIntent.putExtra("currentposition", currentposition); duration = mediaPlayer.getDuration(); sendIntent.putExtra("duration", duration); sendBroadcast(sendIntent); PlayMusic(currentTime); } else if (msg == Common.PlayerMsg.MSG_PLAY_DETAIL) { Intent sendIntent = new Intent(ACTION_UPDATE_INFO); sendIntent.putExtra("isPlaying", isPlaying); sendIntent.putExtra("currentposition", currentposition); duration = mediaPlayer.getDuration(); sendIntent.putExtra("duration", duration); sendBroadcast(sendIntent); mHandler.sendEmptyMessage(1); } return super.onStartCommand(intent, flag, startId); }
2. 播放功能实现
/** * 播放音乐 * * @param <span style="font-family: Arial, Helvetica, sans-serif;">current</span> */ private void PlayMusic(int current) { try { mediaPlayer.reset();// 把各项参数恢复到初始状态 mediaPlayer.setDataSource(path); mediaPlayer.prepare(); // 进行缓冲 mediaPlayer.setOnPreparedListener(new PreparedListener(current));// 注册一个监听器 //mHandler.sendEmptyMessage(1); //更新时间UI } catch (Exception e) { e.printStackTrace(); } } /** * 暂停与开始音乐 */ private void PauseNResumeMusic() { Intent sendIntent = new Intent(ACTION_UPDATE_INFO); // 发送广播,将被Activity组件中的BroadcastReceiver接收到 sendIntent.putExtra("currentposition", currentposition); duration = mediaPlayer.getDuration(); sendIntent.putExtra("duration", duration); if (mediaPlayer != null && mediaPlayer.isPlaying()) { isPlaying = false; sendIntent.putExtra("isPlaying", false); mediaPlayer.pause(); } else { isPlaying = true; sendIntent.putExtra("isPlaying", true); mediaPlayer.start(); } sendBroadcast(sendIntent); } /** * 上一首 */ private void PreviousMusic() { Intent sendIntent = new Intent(ACTION_UPDATE_INFO); isPlaying = true; sendIntent.putExtra("isPlaying", true); sendIntent.putExtra("currentposition", currentposition); // 发送广播,将被Activity组件中的BroadcastReceiver接收到 sendBroadcast(sendIntent); PlayMusic(0); } /** * 下一首 */ private void NextMusic() { Intent sendIntent = new Intent(ACTION_UPDATE_INFO); isPlaying = true; sendIntent.putExtra("isPlaying", true); sendIntent.putExtra("currentposition", currentposition); sendIntent.putExtra("TYPE", type); sendIntent.putExtra("TitleName", titleName); // 发送广播,将被Activity组件中的BroadcastReceiver接收到 sendBroadcast(sendIntent); PlayMusic(0); } @Override public void onDestroy() { if (null != mediaPlayer) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } mHandler.removeMessages(1); } /** * * 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放 * */ private final class PreparedListener implements OnPreparedListener { private int currentTime; public PreparedListener(int currentTime) { this.currentTime = currentTime; Log.e(TAG, "current1 = " + currentTime); } @Override public void onPrepared(MediaPlayer mp) { Log.d(TAG, "onPrepared and start music"); Toast.makeText(MediaPlayerService.this, "开始播放", Toast.LENGTH_SHORT).show(); mediaPlayer.start(); // 开始播放 if (currentTime > 0) { // 如果音乐不是从头播放 Log.e(TAG, "current3 = " + currentTime); mediaPlayer.seekTo(currentTime); } //更新时间 mHandler.sendEmptyMessage(1); //更新 歌曲时间 Intent intent = new Intent(); intent.setAction(ACTION_MUSIC_DURATION); duration = mediaPlayer.getDuration(); intent.putExtra("duration", duration); //通过Intent来传递歌曲的总长度 Log.e(TAG, "[Send Music Duration]duration = " + duration); sendBroadcast(intent); } }
3. 发送广播,请求更新UI
/* * 设置音乐播放完成时候的监听动作 更新UI * */ mediaPlayer.setOnCompletionListener(new OnCompletionListener(){ public void onCompletion(MediaPlayer mp) { currentposition++; //下一首位置 Log.e(TAG,"musicInfos.size() = " + musicInfos.size() ); if (currentposition <= musicInfos.size() - 1) { Intent sendIntent = new Intent(ACTION_UPDATE_INFO); sendIntent.putExtra("currentposition", currentposition); sendIntent.putExtra("isPlaying", true); isPlaying = true; // 发送广播,将被Activity组件中的BroadcastReceiver接收到 sendBroadcast(sendIntent); path = musicInfos.get(currentposition).getUrl(); PlayMusic(0); } }
重要的事情,源码请猛戳 这里 下载
下篇文章 Android音乐播放器 -- 数据处理 会讲讲播发器使用的的数据结构,敬请期待~