You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

567 lines
23 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.example.musicplayer.service;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
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 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 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));
}
}
@Override
public IBinder onBind(Intent arg0) {
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));
} 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 long getCurrentTime() {
return mediaPlayer.getCurrentPosition() / 1000;
}
}
@Override
public void onDestroy() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
@Override
public boolean onUnbind(Intent intent) {
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) {
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);
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()); //发送网络歌曲改变事件
}
//根据播放模式得到下一首歌曲的位置
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;
}
}