package com.susion.boring.music.service; import android.app.Service; import android.content.Context; import android.content.Intent; import android.support.v4.content.LocalBroadcastManager; import com.susion.boring.http.APIHelper; import com.susion.boring.http.CommonObserver; import com.susion.boring.music.mvp.model.PlayListSong; import com.susion.boring.music.mvp.presenter.MusicModelTranslatePresenter; import com.susion.boring.base.service.BaseServiceContract; import com.susion.boring.db.DbManager; import com.susion.boring.music.mvp.model.SimpleSong; import com.susion.boring.db.operate.MusicDbOperator; import com.susion.boring.music.mvp.model.PlayList; import com.susion.boring.music.mvp.model.Song; import com.susion.boring.music.mvp.presenter.MusicPlayQueueControlPresenter; import com.susion.boring.music.mvp.presenter.PlayMusicPresenter; import com.susion.boring.music.mvp.presenter.ServiceReceiverPresenter; import com.susion.boring.music.mvp.contract.MediaPlayerContract; import com.susion.boring.music.mvp.contract.MusicServiceContract; import com.susion.boring.utils.SPUtils; import com.susion.boring.utils.ToastUtils; import java.io.Serializable; import java.util.List; /** * Created by susion on 17/2/13. * 音乐播放服务, 本身并不是一个服务 * 主要管理音乐的播放控制, 音乐队列, 具体控制委托给 PlayMusicControlPresenter、PlayQueueControlPresenter * 通知client有关音乐UI的改变 * <p/> * 接下来的refactor: 把通知客户端UI改变的Action也抽取到一个单独的类中 */ public class MusicPlayerService implements MediaPlayerContract.MediaPlayerRefreshView, MusicServiceContract.Service, BaseServiceContract { private static final String PLAY_NOT_IS_PLAY_LIST = "PLAY_NOT_IS_PLAY_LIST"; private MediaPlayerContract.PlayMusicControlPresenter mMusicPlayControlPresenter; private MusicDbOperator mDbOperator; private BaseServiceContract.ReceiverPresenter mReceiverPresenter; private MusicServiceContract.PlayQueueControlPresenter mPlayQueuePresenter; private boolean mQueueIsPrepare; private Song mSong; //current play music private String mHasLoadPlayListId = PLAY_NOT_IS_PLAY_LIST; private boolean mAutoPlay; private Service mServiceParent; public MusicPlayerService(Service mServiceParent) { this.mServiceParent = mServiceParent; } @Override public void initService() { mQueueIsPrepare = false; mDbOperator = new MusicDbOperator(DbManager.getLiteOrm(), getContext(), SimpleSong.class); mMusicPlayControlPresenter = new PlayMusicPresenter(this, mServiceParent); mReceiverPresenter = new ServiceReceiverPresenter(this); APIHelper.subscribeSimpleRequest(mDbOperator.getInitPlayQueue(), new CommonObserver<List<Song>>() { @Override public void onNext(List<Song> songs) { mQueueIsPrepare = true; mPlayQueuePresenter = new MusicPlayQueueControlPresenter(songs); } }); } @Override public void loadMusicInfo(Song song, boolean autoPlay) { mAutoPlay = autoPlay; if (song != null) { mSong = song; try { mMusicPlayControlPresenter.initMediaPlayer(mSong.audio); } catch (Exception e) { e.printStackTrace(); } } } @Override public void changeMusic(Song song) { if (song == null) { return; } mSong = song; if (mSong.fromPlayList) { APIHelper.subscribeSimpleRequest(new MusicModelTranslatePresenter().checkIfHasPlayUrl(mSong), new CommonObserver<Boolean>() { @Override public void onNext(Boolean flag) { if (flag) { preparePlay(); } } }); } else { if (!mSong.hasDown) { APIHelper.subscribeSimpleRequest(APIHelper.getMusicServices().getSongDetail(Integer.valueOf(mSong.id)), new CommonObserver<PlayListSong>() { @Override public void onNext(PlayListSong songs) { if (songs != null && !songs.getData().isEmpty()) { mSong.audio = songs.getData().get(0).getUrl(); preparePlay(); } } }); } preparePlay(); } } private void preparePlay() { mAutoPlay = true; try { mMusicPlayControlPresenter.initMediaPlayer(mSong.audio); } catch (Exception e) { e.printStackTrace(); } notifyCurrentPlayMusic(true); } @Override public void startCircleMode() { mPlayQueuePresenter.setPlayMode(MusicServiceContract.PlayQueueControlPresenter.CIRCLE_MODE); notifyCurrentMode(); } @Override public void startRandomMode() { mPlayQueuePresenter.setPlayMode(MusicServiceContract.PlayQueueControlPresenter.RANDOM_MODE); notifyCurrentMode(); } @Override public void songToNextPlay(Song song) { if (!mQueueIsPrepare) { return; } if (mPlayQueuePresenter.getPlayQueue().isEmpty()) { changeMusic(song); } mPlayQueuePresenter.addToNextPlay(song); } @Override public void notifyCurrentMode() { int mode = mPlayQueuePresenter.getPlayMode(); Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_REFRESH_MODE); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PLAY_MODE, mode); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public void circlePlayPlayList(final PlayList playList) { if (mPlayQueuePresenter != null && !playList.getId().equals(mHasLoadPlayListId)) { mMusicPlayControlPresenter.stopPlay(); mQueueIsPrepare = false; APIHelper.subscribeSimpleRequest(mPlayQueuePresenter.reLoadPlayQueue(playList), new CommonObserver<Boolean>() { @Override public void onNext(Boolean flag) { if (flag) { mHasLoadPlayListId = playList.getId(); mQueueIsPrepare = true; mPlayQueuePresenter.setPlayMode(MusicServiceContract.PlayQueueControlPresenter.PLAY_LIST_CIRCLE_MODE); playNextMusic(); } } }); } } @Override public void randomPlayPlayList(final PlayList playList) { if (mPlayQueuePresenter != null && !playList.getId().equals(mHasLoadPlayListId)) { mMusicPlayControlPresenter.stopPlay(); mQueueIsPrepare = false; APIHelper.subscribeSimpleRequest(mPlayQueuePresenter.reLoadPlayQueue(playList), new CommonObserver<Boolean>() { @Override public void onNext(Boolean flag) { if (flag) { mHasLoadPlayListId = playList.getId(); mQueueIsPrepare = true; mPlayQueuePresenter.setPlayMode(MusicServiceContract.PlayQueueControlPresenter.RANDOM_MODE); playNextMusic(); } } }); } } @Override public void removeSongFromQueue(Song song) { mPlayQueuePresenter.removeSong(song); } @Override public void startQueueMode() { mPlayQueuePresenter.setPlayMode(MusicServiceContract.PlayQueueControlPresenter.QUEUE_MODE); } @Override public void addMusicToQueue(Song song) { mPlayQueuePresenter.addToPlayQueue(song); } @Override public void getPlayQueue() { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_PLAY_QUEUE); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PLAY_QUEUE, (Serializable) mPlayQueuePresenter.getPlayQueue()); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public Context getContext() { return mServiceParent; } @Override public void updateBufferedProgress(int percent) { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_UPDATE_BUFFERED_PROGRESS); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_BUFFERED_PROGRESS, percent); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public void updatePlayProgress(int curPos, int duration, int max) { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_UPDATE_PLAY_PROGRESS); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PLAY_PROGRESS_CUR_POS, curPos); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PLAY_PROGRESS_DURATION, duration); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PLAY_PROGRESS_MAX_DURATION, mMusicPlayControlPresenter.getDuration()); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public void preparedPlay(int duration) { mPlayQueuePresenter.markCurrentPlayMusic(mSong); if (mAutoPlay) { mMusicPlayControlPresenter.startPlay(); } Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_PLAYER_PREPARED); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_PREPARED_TOTAL_DURATION, duration); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public void informCurrentPlayMusic() { if (mSong != null) { notifyCurrentPlayMusic(mMusicPlayControlPresenter.isPlaying()); return; } String songId = SPUtils.getStringFromConfig(SPUtils.KEY_LAST_PLAY_MUSIC); APIHelper.subscribeSimpleRequest(mDbOperator.query(songId), new CommonObserver<SimpleSong>() { @Override public void onNext(SimpleSong s) { if (s != null) { mSong = s.translateToSong(); notifyCurrentPlayMusic(mMusicPlayControlPresenter.isPlaying()); } } }); } @Override public void notifyCurrentPlayMusic(boolean isPlaying) { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_CURRENT_PLAY_MUSIC); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_CURRENT_PLAY_MUSIC, mSong); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_CURRENT_PLAY_MUSIC_PLAY_STATUS, isPlaying); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } @Override public void informCurrentIfPlayProgress() { if (mMusicPlayControlPresenter.isPrepared()) { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_CURRENT_PLAY_PROGRESS); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_CURRENT_PLAY_PROGRESS, mMusicPlayControlPresenter.getCurrentProgress()); intent.putExtra(MusicServiceInstruction.CLIENT_PARAM_MEDIA_DURATION, mMusicPlayControlPresenter.getDuration()); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } } @Override public void saveLastPlayMusic() { mMusicPlayControlPresenter.stopPlay(); mMusicPlayControlPresenter.saveLastPlayMusic(mSong, mServiceParent); } @Override public void completionPlay() { if (!playQueueIsPrepare()) return; mSong = mPlayQueuePresenter.getNextPlayMusic(); changeMusic(mSong); } @Override public void pausePlay() { mMusicPlayControlPresenter.pausePlay(); } @Override public void updateSong(Song song) { mSong = song; } @Override public void seekTo(Intent intent) { mMusicPlayControlPresenter.seekTo(intent.getIntExtra(MusicServiceInstruction.SERVER_PARAM_SEEK_TO_POS, 0)); if (!mMusicPlayControlPresenter.isPlaying() && mMusicPlayControlPresenter.isPrepared()) { mMusicPlayControlPresenter.startPlay(); } } @Override public void playMusic() { if (!mMusicPlayControlPresenter.isPrepared()) { mAutoPlay = true; return; } mMusicPlayControlPresenter.startPlay(); } @Override public void clear() { saveLastPlayMusic(); mMusicPlayControlPresenter.releaseResource(); mReceiverPresenter.releaseResource(); } @Override public void playNextMusic() { if (!playQueueIsPrepare()) return; changeMusicFromQueue(mPlayQueuePresenter.getNextPlayMusic()); } @Override public void PlayPreMusic() { if (!playQueueIsPrepare()) return; changeMusicFromQueue(mPlayQueuePresenter.getPrePlayMusic()); } private void changeMusicFromQueue(Song song) { if (song == null) { notifyQueueNoMoreMusic(); return; } changeMusic(song); } private void notifyQueueNoMoreMusic() { Intent intent = new Intent(MusicServiceInstruction.CLIENT_RECEIVER_QUEUE_NO_MORE_MUSIC); LocalBroadcastManager.getInstance(mServiceParent).sendBroadcast(intent); } private boolean playQueueIsPrepare() { if (!mQueueIsPrepare) { ToastUtils.showShort("播放队列正在准备"); return false; } return true; } //用长按home调出最近运行历史,在这里面清除软件,可能会调用 @Override public void onTaskMoved() { clear(); } //手动停止, 会被调用 @Override public void onDestroy() { clear(); } }