【备忘】Android音乐播放服务

public class MusicService extends Service
		implements OnPreparedListener, OnSeekCompleteListener, OnCompletionListener,
		OnErrorListener, OnBufferingUpdateListener {

	private static final String TAG = MusicService.class.getSimpleName();
	
	private MediaPlayer mMediaPlayer;

	private static final int MODE_SEQUENCE = 0;
	private static final int MODE_ONE_LOOP = 1;
	private static final int MODE_ALL_LOOP = 2;
	private static final int MODE_RANDOM   = 3;

	private int mCurrPlayMode = MODE_ALL_LOOP;
	
	private int mCurrMusicIndex = 0;
	private int mCurrPosition = 0;
	private Music mMusic;
	private List<MusicInfo> mPlaylist;
	
	@Override
	@Subscribe(threadMode = ThreadMode.MainThread)
	public void onCreate() {
		super.onCreate();
		initMediaPlayer();
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		return new MusicBinder();
	}
	
	private void initMediaPlayer() {
		Log.d(TAG, "init MediaPlayer.");
		
		mMediaPlayer = new MediaPlayer();
		mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
		mMediaPlayer.setWakeMode(this, PowerManager.PARTIAL_WAKE_LOCK);
		mMediaPlayer.setOnPreparedListener(this);
		mMediaPlayer.setOnSeekCompleteListener(this);
		mMediaPlayer.setOnCompletionListener(this);
		mMediaPlayer.setOnErrorListener(this);
		mMediaPlayer.setOnBufferingUpdateListener(this);
		
		mCurrPlayMode = getCurrPlayMode() == -1 ? mCurrPlayMode : getCurrPlayMode();
	}
	
	@Override
	public void onPrepared(MediaPlayer mp) {
		Log.d(TAG, "onPrepared(), start play");
		mMediaPlayer.start();
		EventBus.getDefault().post(new Event.MusicPrepared(mMediaPlayer.getDuration()));
		startTimeRefreshTask();
	}
	
	@Override
	public void onSeekComplete(MediaPlayer mp) {
		Log.d(TAG, "onSeekComplete(), mCurrPosition = " + mCurrPosition 
				+ ", start play");
		mMediaPlayer.start();
		stopTimeRefreshTask();
		startTimeRefreshTask();	
		EventBus.getDefault().post(new Event.OnSeekComplete());
	}
	
	@Override
	public void onCompletion(MediaPlayer mp) {
		Log.d(TAG, "onCompletion(), mCurrPlayMode = " + mCurrPlayMode);
		stopTimeRefreshTask();
		switch (mCurrPlayMode) {
		case MODE_ONE_LOOP:
			mMediaPlayer.start();
			break;
		case MODE_ALL_LOOP:
			startPlay((mCurrMusicIndex + 1) % mPlaylist.size(), 0);
			break;
		case MODE_SEQUENCE:
			playNext();
			break;

		case MODE_RANDOM:
			startPlay(getRandomMusic(), 0);
			break;
		default:
			Log.e(TAG, "invalid play mode.");
			break;
		}
		EventBus.getDefault().post(new Event.OnCompletion());
	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		Event.BufferPercent bufferPercent = Event.BufferPercent.obtain();
		bufferPercent.setPercent(percent);
		EventBus.getDefault().post(bufferPercent);
		
	}
	
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		Log.e(TAG, "onError()");
		mMediaPlayer.reset();
		EventBus.getDefault().post(new Event.MusicPlayError(mPlaylist.get(mCurrMusicIndex) == null ?
				"" : mPlaylist.get(mCurrMusicIndex).getTrack() == null ?
						"" : mPlaylist.get(mCurrMusicIndex).getTrack().getName()));
		stopTimeRefreshTask();
		playNext();
		return true;
	}
	
	private void startPlay(int musicIndex, int position) {
		setCurrentMusic(musicIndex);
		setCurrentPosition(position);
		if (mPlaylist == null || mPlaylist.isEmpty()) {
			Log.e(TAG, "startPlay(), musicIndex = " + musicIndex + ", position = "
					+ position + ", mPlaylist is empty.");
			return;
		}

		MusicInfo musicInfo = mPlaylist.get(musicIndex);
		if (musicInfo == null) {
			Log.e(TAG, "startPlay(), musicIndex = " + musicIndex + ", position = " 
					+ position + ", musicInfo is null.");
			return;
		}
		String playUrl = musicInfo.getPlayInfo() == null ? "" : musicInfo.getPlayInfo().getPlayUrl();
		Logger.d(TAG, "startPlay(), playUrl = " + playUrl);
		
		if (TextUtils.isEmpty(playUrl)) {
			Log.e(TAG, "startPlay(), musicIndex = " + musicIndex + ", position = " 
					+ position + ", playUrl is null.");
			return;
		}
		mMediaPlayer.reset();
		try {
			mMediaPlayer.setDataSource(playUrl);
			mMediaPlayer.prepareAsync();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String musicTitle = mMusic == null ? "" : mMusic.getAlbumTitle();
		TrackItem trackItem = mPlaylist.get(musicIndex) == null ? null : mPlaylist.get(musicIndex).getTrack();
		musicTitle = trackItem == null ? musicTitle : musicTitle + "-" + trackItem.getName();
		EventBus.getDefault().post(new Event.MusicChanged(musicTitle, musicIndex));
		stopTimeRefreshTask();
	}
	
	private int getRandomMusic() {
		return  (int) (Math.random() * mPlaylist.size());
	}

	private void playNext() {
		switch (mCurrPlayMode) {
		case MODE_ONE_LOOP:
			startPlay(mCurrMusicIndex, 0);
			break;
		case MODE_ALL_LOOP:
			startPlay((mCurrMusicIndex + 1) % mPlaylist.size(), 0);
			break;
		case MODE_SEQUENCE:
			if (mCurrMusicIndex + 1 == mPlaylist.size()) {
				Log.d(TAG, "playNext(), no next song.");
				EventBus.getDefault().post(new Event.NoMoreSong(Event.NoMoreSong.TYPE_NO_NEXT));
				return;
			}
			startPlay(mCurrMusicIndex + 1, 0);
			break;

		case MODE_RANDOM:
			startPlay(getRandomMusic(), 0);
			break;
		default:
			Log.e(TAG, "invalid play mode.");
			break;
		}
		Log.d(TAG, "playNext(), mCurrMusicIndex = " + mCurrMusicIndex);
	}
	
	private void playPrevious() {
		switch (mCurrPlayMode) {
		case MODE_ONE_LOOP:
			startPlay(mCurrMusicIndex, 0);
			break;
		case MODE_ALL_LOOP:
			if (mCurrMusicIndex - 1 < 0) {
				startPlay(mPlaylist.size() - 1 , 0);	
			} else {
				startPlay(mCurrMusicIndex - 1, 0);
			}
			break;
		case MODE_SEQUENCE:
			if (mCurrMusicIndex - 1 < 0) {
				Log.d(TAG, "playPrevious(), no previous song.");
				EventBus.getDefault().post(new Event.NoMoreSong(Event.NoMoreSong.TYPE_NO_PREVIOUS));
				return;
			}
			startPlay(mCurrMusicIndex - 1, 0);
			break;

		case MODE_RANDOM:
			startPlay(getRandomMusic(), 0);
			break;
		default:
			Log.e(TAG, "invalid play mode.");
			break;
		}
		Log.d(TAG, "playPrevious(), mCurrMusicIndex = " + mCurrMusicIndex);
	}
	
	private void pausePlay() {
		if (mMediaPlayer.isPlaying()) {
			mCurrPosition = mMediaPlayer.getCurrentPosition();
			mMediaPlayer.pause();
		}
		Log.d(TAG, "pausePlay(), mCurrMusicIndex = " + mCurrMusicIndex
				+ ", currPosition = " + mCurrPosition);
		stopTimeRefreshTask();
		
	}
	
	private void resumePlay() {
		Log.d(TAG, "resumePlay(), mCurrMusicIndex = " + mCurrMusicIndex 
				+ ", currPosition = " + mCurrPosition);
		if (!mMediaPlayer.isPlaying()) {
			mMediaPlayer.start();
			startTimeRefreshTask();
		}
		
	}
	
	private void stopPlay() {
		Log.d(TAG, "stopPlay(), mCurrMusicIndex = " + mCurrMusicIndex);
		if (mMediaPlayer.isPlaying()) {
			mMediaPlayer.stop();
		}
		
	}
	
	private void seekToPlay(int progress) {
		mCurrPosition = progress * 1000;
		Log.d(TAG, "seekToPlay(), mCurrMusicIndex = " + mCurrMusicIndex
				+ ", position = " + mCurrPosition);
		stopTimeRefreshTask();
//		if (mMediaPlayer.isPlaying()) {
//			mMediaPlayer.seekTo(mCurrPosition);
//		} else {
//			startPlay(mCurrMusicIndex, mCurrPosition);
//		}
		mMediaPlayer.seekTo(mCurrPosition);
	}
	
	private void setCurrentMusic(int currMusicIndex) {
		mCurrMusicIndex = currMusicIndex;
	}

	private void setCurrentPosition(int currPosition) {
		mCurrPosition = currPosition;
	}
	
	private void saveCurrPlayMode(int mode) {
		SharedPreferences sp = getSharedPreferences("sp_play_mode", Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sp.edit();
		editor.putInt("play_mode", mode);
		editor.commit();
	}
	
	private int getCurrPlayMode() {
		SharedPreferences sp = getSharedPreferences("sp_play_mode", Context.MODE_PRIVATE);
		int mode = sp.getInt("play_mode", -1);
		Log.d(TAG, "getCurrPlayMode(), play mode = " + mode);
		return mode;
	}
	
	public class MusicBinder extends Binder {
		
		public void play(int musicIndex, int position) {
			startPlay(musicIndex, position);
		}
		
		public void pause() {
			pausePlay();
		}
		
		public void resume() {
			resumePlay();
		}
		
		public void stop() {
			stopPlay();
		}
		
		public void seekTo(int progress) {
			seekToPlay(progress);
		}
		
		public void previous() {
			playPrevious();
		}
		
		public void next() {
			playNext();
		}
		
		public int changePlayMode() {
			mCurrPlayMode = (mCurrPlayMode + 1) % 4;
			saveCurrPlayMode(mCurrPlayMode);
			return mCurrPlayMode;
		}
		
		public int changePlayModeToOneLoop() {
			mCurrPlayMode = MODE_ONE_LOOP;
			saveCurrPlayMode(mCurrPlayMode);
			return mCurrPlayMode;
		}
		
		public int getPlayMode() {
			return mCurrPlayMode;
		}
		
		public void setPlaylist(List<MusicInfo> playlist) {
			mPlaylist = playlist;
		}
		
		public boolean isPlaying() {
			return mMediaPlayer != null && mMediaPlayer.isPlaying();
		}
		
		public void setMusic(Music music) {
			mMusic = music;
		}
	}
	
	private Handler mTimeRefreshHandler = new Handler();
	private Runnable mTimeRefreshTask = new Runnable() {

		@Override
		public void run() {
			if (mMediaPlayer != null) {
				Event.PlayProgress playProgress = Event.PlayProgress.obtain();
				playProgress.setProgress(mMediaPlayer.getCurrentPosition());
				EventBus.getDefault().post(playProgress);
			}
			mTimeRefreshHandler.postDelayed(mTimeRefreshTask, 1000);
		}
	};
	
	private void startTimeRefreshTask() {
		mTimeRefreshHandler.removeCallbacks(mTimeRefreshTask);
		mTimeRefreshHandler.postDelayed(mTimeRefreshTask, 500);
	}
	
	private void stopTimeRefreshTask() {
		mTimeRefreshHandler.removeCallbacks(mTimeRefreshTask);
	}
	
	@Override
	public void onDestroy() {
		Log.d(TAG, "onDestroy()");
		if (mMediaPlayer != null) {
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
		EventBus.getDefault().unregister(this);
		super.onDestroy();
	}

}

发布了29 篇原创文章 · 获赞 15 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/han_han_1/article/details/52861337
今日推荐