Android音乐播放器 -- MediaPlayer Service实现

上一篇文章 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);
			}
		}

MPS的大体功能介绍到这里,使用广播的方法进行构建,确实是一个非常好的学习机会,用过才会真正记牢,希望大家有兴趣多写写代码,做个播放器真心不错~

重要的事情,源码请猛戳 这里 下载

下篇文章 Android音乐播放器 -- 数据处理 会讲讲播发器使用的的数据结构,敬请期待~

你可能感兴趣的:(Broadcast,播放音乐,mediaplayer)