package com.example.musicplayer.service; import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.graphics.BitmapFactory; import android.media.MediaPlayer; import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.example.musicplayer.R; import com.example.musicplayer.app.Api; import com.example.musicplayer.app.Constant; import com.example.musicplayer.entiy.DownloadSong; import com.example.musicplayer.entiy.HistorySong; import com.example.musicplayer.entiy.LocalSong; import com.example.musicplayer.entiy.Love; import com.example.musicplayer.entiy.OnlineSong; import com.example.musicplayer.entiy.Song; import com.example.musicplayer.entiy.SongUrl; import com.example.musicplayer.event.OnlineSongChangeEvent; import com.example.musicplayer.event.OnlineSongErrorEvent; import com.example.musicplayer.event.SongAlbumEvent; import com.example.musicplayer.event.SongCollectionEvent; import com.example.musicplayer.event.SongDownloadedEvent; import com.example.musicplayer.event.SongHistoryEvent; import com.example.musicplayer.event.SongListNumEvent; import com.example.musicplayer.event.SongLocalEvent; import com.example.musicplayer.event.SongStatusEvent; import com.example.musicplayer.model.https.RetrofitFactory; import com.example.musicplayer.util.CommonUtil; import com.example.musicplayer.util.DownloadUtil; import com.example.musicplayer.util.FileUtil; import com.example.musicplayer.view.MainActivity; import org.greenrobot.eventbus.EventBus; import org.litepal.LitePal; import org.litepal.crud.callback.FindMultiCallback; import org.litepal.crud.callback.SaveCallback; import java.io.IOException; import java.util.ArrayList; import java.util.List; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; @SuppressLint("NewApi") public class PlayerService extends Service { private static final String TAG = "PlayerService"; private final int NOTIFICATION_ID = 98; private PlayStatusBinder mPlayStatusBinder = new PlayStatusBinder(); private MediaPlayer mediaPlayer = new MediaPlayer(); //媒体播放器对象 private boolean isPause; //暂停状态 private boolean isPlaying; //是否播放 private List<LocalSong> mLocalSongList; private List<OnlineSong> mSongList; private List<Love> mLoveList; private List<HistorySong> mHistoryList; private List<DownloadSong> mDownloadList; private int mCurrent; private int mListType; private int mPlayMode = Constant.PLAY_ORDER; //播放模式,默认为顺序播放 @Override public void onCreate() { Log.d(TAG, "onCreate: true"); mListType = FileUtil.getSong().getListType(); if (mListType == Constant.LIST_TYPE_ONLINE) { mSongList = LitePal.findAll(OnlineSong.class); } else if (mListType == Constant.LIST_TYPE_LOCAL) { mLocalSongList = LitePal.findAll(LocalSong.class); } else if (mListType == Constant.LIST_TYPE_LOVE) { mLoveList = LitePal.findAll(Love.class); } else if (mListType == Constant.LIST_TYPE_HISTORY) { mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class)); //保证最近播放列表一开始总是第一个 Song song = FileUtil.getSong(); song.setPosition(0); FileUtil.saveSong(song); }else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ mDownloadList = orderDownloadList(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE)); } //开启前台服务 startForeground(NOTIFICATION_ID,getNotification("随心跳动,开启你的音乐旅程!")); } @Override public IBinder onBind(Intent arg0) { Log.d(TAG, "onBind: jsyjst"); mediaPlayer.setOnCompletionListener(mp -> { EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_PAUSE));//暂停广播 mCurrent = FileUtil.getSong().getPosition(); //将歌曲的信息保存起来 if (mListType == Constant.LIST_TYPE_LOCAL) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲 saveLocalSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_ONLINE) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mSongList.size());//根据播放模式来播放下一曲 saveOnlineSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_LOVE) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mLoveList.size());//根据播放模式来播放下一曲 saveLoveInfo(mCurrent); } else if(mListType == Constant.LIST_TYPE_HISTORY){ mCurrent=getNextCurrent(mCurrent, mPlayMode, mHistoryList.size());//根据播放模式来播放下一曲 saveHistoryInfo(mCurrent); }else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ mCurrent=getNextCurrent(mCurrent, mPlayMode, mDownloadList.size());//根据播放模式来播放下一曲 saveDownloadInfo(mCurrent); } if(mListType!=0) { mPlayStatusBinder.play(mListType); }else { mPlayStatusBinder.stop(); } }); /** * MediaPlayer切歌进入setOnCompletionListener的问题 * 因为直接切歌会发生错误,所以增加错误监听器。返回true。就不会回调onCompletion方法了。 */ mediaPlayer.setOnErrorListener((mp, what, extra) -> true); return mPlayStatusBinder; } public class PlayStatusBinder extends Binder{ public void setPlayMode(int mode){ mPlayMode = mode; } public void getHistoryList() { mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class)); //保证最近播放列表一开始总是第一个 Song song = FileUtil.getSong(); song.setPosition(0); FileUtil.saveSong(song); } /** * 播放音乐 * * @param */ public void play(int listType) { try { mListType = listType; if (mListType == Constant.LIST_TYPE_ONLINE) { mSongList = LitePal.findAll(OnlineSong.class); EventBus.getDefault().post(new SongAlbumEvent()); } else if (mListType == Constant.LIST_TYPE_LOCAL) { mLocalSongList = LitePal.findAll(LocalSong.class); EventBus.getDefault().post(new SongLocalEvent()); //发送本地歌曲改变事件 } else if (mListType == Constant.LIST_TYPE_LOVE) { mLoveList = orderList(LitePal.findAll(Love.class)); EventBus.getDefault().post(new SongCollectionEvent(true));//发送歌曲改变事件 } else if (mListType == Constant.LIST_TYPE_HISTORY) { EventBus.getDefault().post(new SongHistoryEvent()); //发送随机歌曲改变事件 }else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ mDownloadList =orderDownloadList(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE)); EventBus.getDefault().post(new SongDownloadedEvent()); //发送下载歌曲改变的消息 } mCurrent = FileUtil.getSong().getPosition(); mediaPlayer.reset();//把各项参数恢复到初始状态 if (mListType == Constant.LIST_TYPE_LOCAL) { mediaPlayer.setDataSource(mLocalSongList.get(mCurrent).getUrl()); startPlay(); } else if (mListType == Constant.LIST_TYPE_ONLINE) { getSongUrl(mSongList.get(mCurrent).getSongId()); } else if (mListType == Constant.LIST_TYPE_LOVE) { mediaPlayer.setDataSource(mLoveList.get(mCurrent).getUrl()); startPlay(); } else if(mListType == Constant.LIST_TYPE_HISTORY){ mediaPlayer.setDataSource(mHistoryList.get(mCurrent).getUrl()); startPlay(); }else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ Log.d(TAG, "play: "+mDownloadList.get(mCurrent).getUrl()); mediaPlayer.setDataSource(mDownloadList.get(mCurrent).getUrl()); startPlay(); } } catch (Exception e) { e.printStackTrace(); } } //播放搜索歌曲 public void playOnline() { try { mediaPlayer.reset(); mediaPlayer.setDataSource(FileUtil.getSong().getUrl()); mediaPlayer.prepare(); isPlaying = true; saveToHistoryTable(); mediaPlayer.start(); EventBus.getDefault().post(new OnlineSongChangeEvent()); //发送网络歌曲改变事件 EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_CHANGE)); //改变通知栏歌曲 Song song = FileUtil.getSong(); getNotificationManager().notify(NOTIFICATION_ID, getNotification(song.getSongName()+" - "+song.getSinger())); } catch (Exception e) { EventBus.getDefault().post(new OnlineSongErrorEvent()); e.printStackTrace(); } } /** * 暂停音乐 */ public void pause() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { isPlaying = false; mediaPlayer.pause(); isPause = true; EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_PAUSE));//发送暂停的广播给主活动 } } public void resume() { if (isPause) { mediaPlayer.start(); isPlaying = true; isPause = false; EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME)); } } public void next() { EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME)); mCurrent = FileUtil.getSong().getPosition(); if (mListType == Constant.LIST_TYPE_LOCAL) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲 saveLocalSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_ONLINE) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mSongList.size());//根据播放模式来播放下一曲 saveOnlineSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_LOVE) { mCurrent=getNextCurrent(mCurrent, mPlayMode, mLoveList.size());//根据播放模式来播放下一曲 saveLoveInfo(mCurrent); } else if(mListType == Constant.LIST_TYPE_HISTORY){ mCurrent=getNextCurrent(mCurrent, mPlayMode, mHistoryList.size());//根据播放模式来播放下一曲 saveHistoryInfo(mCurrent); }else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ mCurrent=getNextCurrent(mCurrent, mPlayMode, mDownloadList.size());//根据播放模式来播放下一曲 saveDownloadInfo(mCurrent); } if(mListType!=0) mPlayStatusBinder.play(mListType); } public void last() { EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME));//暂停广播 mCurrent = FileUtil.getSong().getPosition(); if (mListType == Constant.LIST_TYPE_LOCAL) { mCurrent = getLastCurrent(mCurrent,mPlayMode,mLocalSongList.size()); saveLocalSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_ONLINE) { mCurrent = getLastCurrent(mCurrent,mPlayMode,mSongList.size()); saveOnlineSongInfo(mCurrent); } else if (mListType == Constant.LIST_TYPE_LOVE) { mCurrent = getLastCurrent(mCurrent,mPlayMode,mLoveList.size()); saveLoveInfo(mCurrent); } else if(mListType == Constant.LIST_TYPE_HISTORY){ mCurrent = getLastCurrent(mCurrent,mPlayMode,mHistoryList.size()); saveHistoryInfo(mCurrent); } else if(mListType == Constant.LIST_TYPE_DOWNLOAD){ mCurrent = getLastCurrent(mCurrent,mPlayMode,mDownloadList.size()); saveDownloadInfo(mCurrent); } if(mListType!=0) mPlayStatusBinder.play(mListType); } /** * 停止音乐 */ public void stop() { if (mediaPlayer != null) { isPlaying = false; mediaPlayer.stop(); try { mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数 } catch (Exception e) { e.printStackTrace(); } } } public boolean isPlaying() { return isPlaying; } public MediaPlayer getMediaPlayer() { return mediaPlayer; } public PlayerService getPlayerService(){ return PlayerService.this; } public long getCurrentTime() { return mediaPlayer.getCurrentPosition() / 1000; } } @Override public void onDestroy() { Log.d(TAG, "onDestroy: 服务被销毁了"); if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } stopForeground(true); } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind: jsyjst"); return true; } //保存本地音乐列表的信息 private void saveLocalSongInfo(int current) { //将歌曲的信息保存起来 mLocalSongList = LitePal.findAll(LocalSong.class); Song song = new Song(); LocalSong localSong = mLocalSongList.get(current); song.setPosition(current); song.setSongName(localSong.getName()); song.setSinger(localSong.getSinger()); song.setDuration(localSong.getDuration()); song.setUrl(localSong.getUrl()); song.setImgUrl(localSong.getPic()); song.setSongId(localSong.getSongId()); song.setQqId(localSong.getQqId()); song.setOnline(false); song.setListType(Constant.LIST_TYPE_LOCAL); FileUtil.saveSong(song); } //保存网络专辑列表的信息 private void saveOnlineSongInfo(int current) { mSongList = LitePal.findAll(OnlineSong.class); Song song = new Song(); song.setPosition(current); song.setSongId(mSongList.get(current).getSongId()); song.setSongName(mSongList.get(current).getName()); song.setSinger(mSongList.get(current).getSinger()); song.setDuration(mSongList.get(current).getDuration()); song.setUrl(mSongList.get(current).getUrl()); song.setImgUrl(mSongList.get(current).getPic()); song.setOnline(true); song.setListType(Constant.LIST_TYPE_ONLINE); song.setMediaId(mSongList.get(current).getMediaId()); FileUtil.saveSong(song); } //保存我的收藏的列表的信息 private void saveLoveInfo(int current) { mLoveList = orderList(LitePal.findAll(Love.class)); Love love = mLoveList.get(current); Song song = new Song(); song.setPosition(current); song.setSongId(love.getSongId()); song.setQqId(love.getQqId()); song.setSongName(love.getName()); song.setSinger(love.getSinger()); song.setUrl(love.getUrl()); song.setImgUrl(love.getPic()); song.setListType(Constant.LIST_TYPE_LOVE); song.setOnline(love.isOnline()); song.setDuration(love.getDuration()); song.setMediaId(love.getMediaId()); song.setDownload(love.isDownload()); FileUtil.saveSong(song); } //保存下载列表的信息 private void saveDownloadInfo(int current){ DownloadSong downloadSong = mDownloadList.get(current); Song song = new Song(); song.setPosition(current); song.setSongId(downloadSong.getSongId()); song.setSongName(downloadSong.getName()); song.setSinger(downloadSong.getSinger()); song.setUrl(downloadSong.getUrl()); song.setImgUrl(downloadSong.getPic()); song.setListType(Constant.LIST_TYPE_DOWNLOAD); song.setOnline(false); song.setDuration(downloadSong.getDuration()); song.setMediaId(downloadSong.getMediaId()); song.setDownload(true); FileUtil.saveSong(song); } //保存我的收藏的列表的信息 private void saveHistoryInfo(int current) { HistorySong historySong = mHistoryList.get(current); Song song = new Song(); song.setPosition(current); song.setSongId(historySong.getSongId()); song.setQqId(historySong.getQqId()); song.setSongName(historySong.getName()); song.setSinger(historySong.getSinger()); song.setUrl(historySong.getUrl()); song.setImgUrl(historySong.getPic()); song.setListType(Constant.LIST_TYPE_HISTORY); song.setOnline(historySong.isOnline()); song.setDuration(historySong.getDuration()); song.setMediaId(historySong.getMediaId()); song.setDownload(historySong.isDownload()); FileUtil.saveSong(song); } //将歌曲保存到最近播放的数据库中 private void saveToHistoryTable() { final Song song = FileUtil.getSong(); LitePal.where("songId=?", song.getSongId()).findAsync(HistorySong.class) .listen(new FindMultiCallback<HistorySong>() { @Override public void onFinish(List<HistorySong> list) { if (list.size() == 1) { LitePal.deleteAll(HistorySong.class, "songId=?", song.getSongId()); } final HistorySong history = new HistorySong(); history.setSongId(song.getSongId()); history.setQqId(song.getQqId()); history.setName(song.getSongName()); history.setSinger(song.getSinger()); history.setUrl(song.getUrl()); history.setPic(song.getImgUrl()); history.setOnline(song.isOnline()); history.setDuration(song.getDuration()); history.setMediaId(song.getMediaId()); history.setDownload(song.isDownload()); history.saveAsync().listen(new SaveCallback() { @Override public void onFinish(boolean success) { if (success) { //告诉主界面最近播放的数目需要改变 EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_HISTORY)); if (LitePal.findAll(HistorySong.class).size() > Constant.HISTORY_MAX_SIZE) { LitePal.delete(HistorySong.class, LitePal.findFirst(HistorySong.class).getId()); } } } }); } }); } //对数据库进行倒叙排序 private List orderList(List<Love> tempList) { List<Love> loveList = new ArrayList<>(); loveList.clear(); for (int i = tempList.size() - 1; i >= 0; i--) { loveList.add(tempList.get(i)); } return loveList; } private List<DownloadSong> orderDownloadList(List<DownloadSong> tempList) { List<DownloadSong> downloadSongList = new ArrayList<>(); downloadSongList.clear(); for (int i = tempList.size() - 1; i >= 0; i--) { downloadSongList.add(tempList.get(i)); } return downloadSongList; } private List<HistorySong> orderHistoryList(List<HistorySong> tempList) { List<HistorySong> historySongList = new ArrayList<>(); historySongList.clear(); for (int i = tempList.size() - 1; i >= 0; i--) { historySongList.add(tempList.get(i)); } return historySongList; } //网络请求获取播放地址 private void getSongUrl(String songId) { Log.d(TAG, "getSongUrl: "+Api.SONG_URL_DATA_LEFT + songId + Api.SONG_URL_DATA_RIGHT); RetrofitFactory.createRequestOfSongUrl().getSongUrl(Api.SONG_URL_DATA_LEFT + songId + Api.SONG_URL_DATA_RIGHT) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new Observer<SongUrl>() { @Override public void onSubscribe(Disposable disposable) { } @Override public void onNext(SongUrl songUrl) { if (songUrl.getCode() == 0) { String sip = songUrl.getReq_0().getData().getSip().get(0); String purl = songUrl.getReq_0().getData().getMidurlinfo().get(0).getPurl(); if(purl.equals("")) { CommonUtil.showToast(PlayerService.this,"该歌曲暂时没有版权,试试搜索其它歌曲吧"); return; } Song song = FileUtil.getSong(); assert song != null; song.setUrl(sip + purl); FileUtil.saveSong(song); try { mediaPlayer.setDataSource(sip + purl); Log.d(TAG, "onNext:jsyjst ="+sip+purl); startPlay(); } catch (IOException e) { e.printStackTrace(); } } else { Log.d(TAG, "onNext:" + songUrl.getCode() + ":获取不到歌曲播放地址"); } } @Override public void onError(Throwable throwable) { Log.d(TAG, "onError: "+throwable.toString()); } @Override public void onComplete() { } }); } //开始播放 private void startPlay() throws IOException { mediaPlayer.prepare(); //进行缓冲 isPlaying = true; mediaPlayer.start(); saveToHistoryTable(); EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_CHANGE));//发送所有歌曲改变事件 EventBus.getDefault().post(new OnlineSongChangeEvent()); //发送网络歌曲改变事件 //改变通知栏歌曲 Song song = FileUtil.getSong(); getNotificationManager().notify(NOTIFICATION_ID, getNotification(song.getSongName()+" - "+song.getSinger())); } //根据播放模式得到下一首歌曲的位置 private int getNextCurrent(int current, int playMode, int len) { int res; if (playMode == Constant.PLAY_ORDER) { res = (current + 1) % len; } else if (playMode == Constant.PLAY_RANDOM) { res = (current + (int) (Math.random() * len)) % len; } else { res = current; } return res; } //根据播放模式得到上一首歌曲的位置 private int getLastCurrent(int current, int playMode, int len) { int res; if (playMode == Constant.PLAY_ORDER) { res = current - 1 == -1 ? len-1 : current - 1; } else if (playMode == Constant.PLAY_RANDOM) { res = (current + (int) (Math.random() * len)) % len; } else { res = current; } return res; } //开启前台服务 private NotificationManager getNotificationManager() { return (NotificationManager) getSystemService(NOTIFICATION_SERVICE); } //设置通知栏标题 private Notification getNotification(String title) { Intent intent = new Intent(this, MainActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { String id = "play"; String name = "播放歌曲"; NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW); getNotificationManager().createNotificationChannel(mChannel); Notification.Builder builder = new Notification.Builder(this, id); builder.setSmallIcon(R.mipmap.icon); builder.setContentIntent(pi); builder.setContentTitle(title); return builder.build(); } else { NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "play"); builder.setSmallIcon(R.mipmap.icon); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.icon)); builder.setContentIntent(pi); builder.setContentTitle(title); return builder.build(); } } }