@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
import android.app.Notification ;
import android.app.Notification ;
import android.app.NotificationChannel ;
import android.app.NotificationChannel ;
import android.app.NotificationManager ;
import android.app.NotificationManager ;
import android.app.PendingIntent ;
import android.app.Service ;
import android.app.Service ;
import android.content.Intent ;
import android.content.Intent ;
import android.graphics.BitmapFactory ;
import android.graphics.BitmapFactory ;
@ -54,29 +53,45 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable ;
import io.reactivex.disposables.Disposable ;
import io.reactivex.schedulers.Schedulers ;
import io.reactivex.schedulers.Schedulers ;
// 抑制新 API 警告
@SuppressLint ( "NewApi" )
@SuppressLint ( "NewApi" )
public class PlayerService extends Service {
public class PlayerService extends Service {
// 日志标记
private static final String TAG = "PlayerService" ;
private static final String TAG = "PlayerService" ;
// 通知的唯一标识
private final int NOTIFICATION_ID = 98 ;
private final int NOTIFICATION_ID = 98 ;
// 自定义的 Binder 类,用于在服务和客户端之间通信
private PlayStatusBinder mPlayStatusBinder = new PlayStatusBinder ( ) ;
private PlayStatusBinder mPlayStatusBinder = new PlayStatusBinder ( ) ;
private MediaPlayer mediaPlayer = new MediaPlayer ( ) ; //媒体播放器对象
// 媒体播放器对象,用于播放音乐
private boolean isPause ; //暂停状态
private MediaPlayer mediaPlayer = new MediaPlayer ( ) ;
private boolean isPlaying ; //是否播放
// 暂停状态标记
private boolean isPause ;
// 是否正在播放标记
private boolean isPlaying ;
// 本地歌曲列表
private List < LocalSong > mLocalSongList ;
private List < LocalSong > mLocalSongList ;
// 在线歌曲列表
private List < OnlineSong > mSongList ;
private List < OnlineSong > mSongList ;
// 收藏歌曲列表
private List < Love > mLoveList ;
private List < Love > mLoveList ;
// 历史播放歌曲列表
private List < HistorySong > mHistoryList ;
private List < HistorySong > mHistoryList ;
// 下载歌曲列表
private List < DownloadSong > mDownloadList ;
private List < DownloadSong > mDownloadList ;
// 当前歌曲的索引
private int mCurrent ;
private int mCurrent ;
// 列表类型(在线、本地、收藏、历史、下载)
private int mListType ;
private int mListType ;
private int mPlayMode = Constant . PLAY_ORDER ; //播放模式, 默认为顺序播放
// 播放模式, 默认为顺序播放
private int mPlayMode = Constant . PLAY_ORDER ;
@Override
@Override
public void onCreate ( ) {
public void onCreate ( ) {
// 输出日志,服务创建
Log . d ( TAG , "onCreate: true" ) ;
Log . d ( TAG , "onCreate: true" ) ;
// 获取存储的歌曲列表类型
mListType = FileUtil . getSong ( ) . getListType ( ) ;
mListType = FileUtil . getSong ( ) . getListType ( ) ;
// 根据不同的列表类型从数据库中获取相应的歌曲列表
if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
mSongList = LitePal . findAll ( OnlineSong . class ) ;
mSongList = LitePal . findAll ( OnlineSong . class ) ;
} else if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
} else if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
@ -92,56 +107,71 @@ public class PlayerService extends Service {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
mDownloadList = orderDownloadList ( DownloadUtil . getSongFromFile ( Api . STORAGE_SONG_FILE ) ) ;
mDownloadList = orderDownloadList ( DownloadUtil . getSongFromFile ( Api . STORAGE_SONG_FILE ) ) ;
}
}
// 开启前台服务并显示通知
//开启前台服务
startForeground ( NOTIFICATION_ID , getNotification ( "随心跳动,开启你的音乐旅程!" ) ) ;
startForeground ( NOTIFICATION_ID , getNotification ( "随心跳动,开启你的音乐旅程!" ) ) ;
}
}
@Override
@Override
public IBinder onBind ( Intent arg0 ) {
public IBinder onBind ( Intent arg0 ) {
// 输出日志,服务绑定
Log . d ( TAG , "onBind: jsyjst" ) ;
Log . d ( TAG , "onBind: jsyjst" ) ;
// 设置媒体播放器播放完成的监听器
mediaPlayer . setOnCompletionListener ( mp - > {
mediaPlayer . setOnCompletionListener ( mp - > {
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_PAUSE ) ) ; //暂停广播
// 发送歌曲暂停事件
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_PAUSE ) ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
// 将歌曲的信息保存起来
// 根据播放模式播放下一曲并保存歌曲信息
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果列表类型是本地歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ;
// 根据当前播放位置、播放模式和本地歌曲列表的长度,调用 getNextCurrent 方法获取下一首歌曲的位置
saveLocalSongInfo ( mCurrent ) ;
saveLocalSongInfo ( mCurrent ) ;
// 保存本地歌曲列表中对应位置的歌曲信息,将当前播放位置、歌曲名称、歌手等信息存储到文件中
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果列表类型是在线歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ;
// 根据当前播放位置、播放模式和在线歌曲列表的长度,调用 getNextCurrent 方法获取下一首歌曲的位置
saveOnlineSongInfo ( mCurrent ) ;
saveOnlineSongInfo ( mCurrent ) ;
// 保存在线歌曲列表中对应位置的歌曲信息,将当前播放位置、歌曲名称、歌手等信息存储到文件中
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果列表类型是收藏歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ;
// 根据当前播放位置、播放模式和收藏歌曲列表的长度,调用 getNextCurrent 方法获取下一首歌曲的位置
saveLoveInfo ( mCurrent ) ;
saveLoveInfo ( mCurrent ) ;
// 保存收藏歌曲列表中对应位置的歌曲信息,将当前播放位置、歌曲名称、歌手等信息存储到文件中
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果列表类型是历史歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ;
// 根据当前播放位置、播放模式和历史歌曲列表的长度,调用 getNextCurrent 方法获取下一首歌曲的位置
saveHistoryInfo ( mCurrent ) ;
saveHistoryInfo ( mCurrent ) ;
// 保存历史歌曲列表中对应位置的歌曲信息,将当前播放位置、歌曲名称、歌手等信息存储到文件中
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果列表类型是下载歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ;
// 根据当前播放位置、播放模式和下载歌曲列表的长度,调用 getNextCurrent 方法获取下一首歌曲的位置
saveDownloadInfo ( mCurrent ) ;
saveDownloadInfo ( mCurrent ) ;
// 保存下载歌曲列表中对应位置的歌曲信息,将当前播放位置、歌曲名称、歌手等信息存储到文件中
}
}
if ( mListType ! = 0 ) {
if ( mListType ! = 0 ) {
// 如果列表类型不为 0
mPlayStatusBinder . play ( mListType ) ;
mPlayStatusBinder . play ( mListType ) ;
// 调用 PlayStatusBinder 的 play 方法,根据当前列表类型播放歌曲
} else {
} else {
mPlayStatusBinder . stop ( ) ;
mPlayStatusBinder . stop ( ) ;
// 否则调用 PlayStatusBinder 的 stop 方法,停止播放
}
}
} ) ;
// 设置媒体播放器错误监听器,防止直接切歌时发生错误
/ * *
* MediaPlayer 切 歌 进 入 setOnCompletionListener 的 问 题
* 因 为 直 接 切 歌 会 发 生 错 误 , 所 以 增 加 错 误 监 听 器 。 返 回 true 。 就 不 会 回 调 onCompletion 方 法 了 。
* /
mediaPlayer . setOnErrorListener ( ( mp , what , extra ) - > true ) ;
mediaPlayer . setOnErrorListener ( ( mp , what , extra ) - > true ) ;
return mPlayStatusBinder ;
return mPlayStatusBinder ;
}
}
public class PlayStatusBinder extends Binder {
public class PlayStatusBinder extends Binder {
// 设置播放模式
public void setPlayMode ( int mode ) {
public void setPlayMode ( int mode ) {
mPlayMode = mode ;
mPlayMode = mode ;
}
}
// 获取历史播放列表
public void getHistoryList ( ) {
public void getHistoryList ( ) {
mHistoryList = orderHistoryList ( LitePal . findAll ( HistorySong . class ) ) ;
mHistoryList = orderHistoryList ( LitePal . findAll ( HistorySong . class ) ) ;
// 保证最近播放列表一开始总是第一个
// 保证最近播放列表一开始总是第一个
@ -150,176 +180,253 @@ public class PlayerService extends Service {
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
/ * *
// 播放音乐
* 播 放 音 乐
*
* @param
* /
public void play ( int listType ) {
public void play ( int listType ) {
try {
try {
mListType = listType ;
mListType = listType ;
// 根据不同的列表类型更新列表并发送相应的事件
if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
// 如果列表类型是在线歌曲列表
mSongList = LitePal . findAll ( OnlineSong . class ) ;
mSongList = LitePal . findAll ( OnlineSong . class ) ;
// 使用 LitePal 从数据库中查找所有的 OnlineSong 类型的歌曲,并将结果存储在 mSongList 中
EventBus . getDefault ( ) . post ( new SongAlbumEvent ( ) ) ;
EventBus . getDefault ( ) . post ( new SongAlbumEvent ( ) ) ;
// 通过 EventBus 发送 SongAlbumEvent 事件,可能用于通知其他组件更新 UI 或执行相应操作
} else if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
} else if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
// 如果列表类型是本地歌曲列表
mLocalSongList = LitePal . findAll ( LocalSong . class ) ;
mLocalSongList = LitePal . findAll ( LocalSong . class ) ;
EventBus . getDefault ( ) . post ( new SongLocalEvent ( ) ) ; //发送本地歌曲改变事件
// 使用 LitePal 从数据库中查找所有的 LocalSong 类型的歌曲,并将结果存储在 mLocalSongList 中
EventBus . getDefault ( ) . post ( new SongLocalEvent ( ) ) ;
// 通过 EventBus 发送 SongLocalEvent 事件,可能用于通知其他组件更新 UI 或执行相应操作
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
// 如果列表类型是收藏歌曲列表
mLoveList = orderList ( LitePal . findAll ( Love . class ) ) ;
mLoveList = orderList ( LitePal . findAll ( Love . class ) ) ;
EventBus . getDefault ( ) . post ( new SongCollectionEvent ( true ) ) ; //发送歌曲改变事件
// 先使用 LitePal 从数据库中查找所有的 Love 类型的歌曲,然后调用 orderList 方法对结果进行排序,将排序后的列表存储在 mLoveList 中
EventBus . getDefault ( ) . post ( new SongCollectionEvent ( true ) ) ;
// 通过 EventBus 发送 SongCollectionEvent 事件,可能用于通知其他组件更新 UI 或执行相应操作
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
EventBus . getDefault ( ) . post ( new SongHistoryEvent ( ) ) ; //发送随机歌曲改变事件
// 如果列表类型是历史歌曲列表
EventBus . getDefault ( ) . post ( new SongHistoryEvent ( ) ) ;
// 通过 EventBus 发送 SongHistoryEvent 事件,可能用于通知其他组件更新 UI 或执行相应操作
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
// 如果列表类型是下载歌曲列表
mDownloadList = orderDownloadList ( DownloadUtil . getSongFromFile ( Api . STORAGE_SONG_FILE ) ) ;
mDownloadList = orderDownloadList ( DownloadUtil . getSongFromFile ( Api . STORAGE_SONG_FILE ) ) ;
EventBus . getDefault ( ) . post ( new SongDownloadedEvent ( ) ) ; //发送下载歌曲改变的消息
// 通过 DownloadUtil 从文件中获取下载歌曲列表,并调用 orderDownloadList 方法对结果进行排序,将排序后的列表存储在 mDownloadList 中
EventBus . getDefault ( ) . post ( new SongDownloadedEvent ( ) ) ;
// 通过 EventBus 发送 SongDownloadedEvent 事件,可能用于通知其他组件更新 UI 或执行相应操作
}
}
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
mediaPlayer . reset ( ) ; //把各项参数恢复到初始状态
// 从 FileUtil 中获取当前歌曲的位置信息,并存储在 mCurrent 中
// 重置媒体播放器状态
mediaPlayer . reset ( ) ;
// 根据列表类型设置数据源并开始播放
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
// 如果列表类型是本地歌曲列表
mediaPlayer . setDataSource ( mLocalSongList . get ( mCurrent ) . getUrl ( ) ) ;
mediaPlayer . setDataSource ( mLocalSongList . get ( mCurrent ) . getUrl ( ) ) ;
// 从 mLocalSongList 中获取当前歌曲的 URL, 并将其设置为媒体播放器 mediaPlayer 的数据源
startPlay ( ) ;
startPlay ( ) ;
// 调用 startPlay 方法开始播放音乐
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
// 如果列表类型是在线歌曲列表
getSongUrl ( mSongList . get ( mCurrent ) . getSongId ( ) ) ;
getSongUrl ( mSongList . get ( mCurrent ) . getSongId ( ) ) ;
// 获取当前在线歌曲的歌曲 ID, 然后调用 getSongUrl 方法通过网络请求获取该歌曲的播放 URL
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
// 如果列表类型是收藏歌曲列表
mediaPlayer . setDataSource ( mLoveList . get ( mCurrent ) . getUrl ( ) ) ;
mediaPlayer . setDataSource ( mLoveList . get ( mCurrent ) . getUrl ( ) ) ;
// 从 mLoveList 中获取当前歌曲的 URL, 并将其设置为媒体播放器 mediaPlayer 的数据源
startPlay ( ) ;
startPlay ( ) ;
// 调用 startPlay 方法开始播放音乐
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
// 如果列表类型是历史歌曲列表
mediaPlayer . setDataSource ( mHistoryList . get ( mCurrent ) . getUrl ( ) ) ;
mediaPlayer . setDataSource ( mHistoryList . get ( mCurrent ) . getUrl ( ) ) ;
// 从 mHistoryList 中获取当前歌曲的 URL, 并将其设置为媒体播放器 mediaPlayer 的数据源
startPlay ( ) ;
startPlay ( ) ;
// 调用 startPlay 方法开始播放音乐
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
// 如果列表类型是下载歌曲列表
Log . d ( TAG , "play: " + mDownloadList . get ( mCurrent ) . getUrl ( ) ) ;
Log . d ( TAG , "play: " + mDownloadList . get ( mCurrent ) . getUrl ( ) ) ;
// 打印当前下载歌曲的 URL 到日志
mediaPlayer . setDataSource ( mDownloadList . get ( mCurrent ) . getUrl ( ) ) ;
mediaPlayer . setDataSource ( mDownloadList . get ( mCurrent ) . getUrl ( ) ) ;
// 从 mDownloadList 中获取当前歌曲的 URL, 并将其设置为媒体播放器 mediaPlayer 的数据源
startPlay ( ) ;
startPlay ( ) ;
// 调用 startPlay 方法开始播放音乐
}
}
} catch ( Exception e ) {
} catch ( Exception e ) {
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
}
}
}
// 播放搜索歌曲
// 播放搜索歌曲
public void playOnline ( ) {
public void playOnline ( ) {
try {
try {
mediaPlayer . reset ( ) ;
mediaPlayer . reset ( ) ;
// 设置数据源,准备并开始播放
mediaPlayer . setDataSource ( FileUtil . getSong ( ) . getUrl ( ) ) ;
mediaPlayer . setDataSource ( FileUtil . getSong ( ) . getUrl ( ) ) ;
mediaPlayer . prepare ( ) ;
mediaPlayer . prepare ( ) ;
isPlaying = true ;
isPlaying = true ;
// 保存到历史播放表
saveToHistoryTable ( ) ;
saveToHistoryTable ( ) ;
mediaPlayer . start ( ) ;
mediaPlayer . start ( ) ;
EventBus . getDefault ( ) . post ( new OnlineSongChangeEvent ( ) ) ; //发送网络歌曲改变事件
// 发送在线歌曲改变事件和歌曲状态改变事件
EventBus . getDefault ( ) . post ( new OnlineSongChangeEvent ( ) ) ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_CHANGE ) ) ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_CHANGE ) ) ;
// 改变通知栏歌曲
// 改变通知栏歌曲信息
Song song = FileUtil . getSong ( ) ;
Song song = FileUtil . getSong ( ) ;
getNotificationManager ( ) . notify ( NOTIFICATION_ID ,
getNotificationManager ( ) . notify ( NOTIFICATION_ID ,
getNotification ( song . getSongName ( ) + " - " + song . getSinger ( ) ) ) ;
getNotification ( song . getSongName ( ) + " - " + song . getSinger ( ) ) ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
// 发送在线歌曲错误事件
EventBus . getDefault ( ) . post ( new OnlineSongErrorEvent ( ) ) ;
EventBus . getDefault ( ) . post ( new OnlineSongErrorEvent ( ) ) ;
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
}
}
}
}
// 暂停音乐
/ * *
* 暂 停 音 乐
* /
public void pause ( ) {
public void pause ( ) {
if ( mediaPlayer ! = null & & mediaPlayer . isPlaying ( ) ) {
if ( mediaPlayer ! = null & & mediaPlayer . isPlaying ( ) ) {
isPlaying = false ;
isPlaying = false ;
mediaPlayer . pause ( ) ;
mediaPlayer . pause ( ) ;
isPause = true ;
isPause = true ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_PAUSE ) ) ; //发送暂停的广播给主活动
// 发送暂停广播
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_PAUSE ) ) ;
}
}
}
}
// 恢复播放
public void resume ( ) {
public void resume ( ) {
if ( isPause ) {
if ( isPause ) {
mediaPlayer . start ( ) ;
mediaPlayer . start ( ) ;
isPlaying = true ;
isPlaying = true ;
isPause = false ;
isPause = false ;
// 发送恢复播放广播
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ;
}
}
}
}
// 播放下一首歌曲
public void next ( ) {
public void next ( ) {
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
// 根据播放模式获取下一首歌曲的索引并保存歌曲信息
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果当前歌曲列表类型是本地歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ;
// 调用 getNextCurrent 方法,根据当前歌曲位置、播放模式和本地歌曲列表的大小来计算下一首歌曲的位置
// 此方法会根据播放模式(顺序、随机等)计算下一首歌曲的位置
saveLocalSongInfo ( mCurrent ) ;
saveLocalSongInfo ( mCurrent ) ;
// 调用 saveLocalSongInfo 方法, 将本地歌曲列表中当前位置( mCurrent) 的歌曲信息保存起来
// 可能会保存歌曲的位置、名称、歌手、时长、URL 等信息
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果当前歌曲列表类型是在线歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ;
// 同样调用 getNextCurrent 方法,根据当前歌曲位置、播放模式和在线歌曲列表的大小计算下一首歌曲的位置
saveOnlineSongInfo ( mCurrent ) ;
saveOnlineSongInfo ( mCurrent ) ;
// 调用 saveOnlineSongInfo 方法, 将在线歌曲列表中当前位置( mCurrent) 的歌曲信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果当前歌曲列表类型是收藏歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ;
// 调用 getNextCurrent 方法,根据当前歌曲位置、播放模式和收藏歌曲列表的大小计算下一首歌曲的位置
saveLoveInfo ( mCurrent ) ;
saveLoveInfo ( mCurrent ) ;
// 调用 saveLoveInfo 方法, 将收藏歌曲列表中当前位置( mCurrent) 的歌曲信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果当前歌曲列表类型是历史歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ;
// 调用 getNextCurrent 方法,根据当前歌曲位置、播放模式和历史歌曲列表的大小计算下一首歌曲的位置
saveHistoryInfo ( mCurrent ) ;
saveHistoryInfo ( mCurrent ) ;
// 调用 saveHistoryInfo 方法, 将历史歌曲列表中当前位置( mCurrent) 的歌曲信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ; //根据播放模式来播放下一曲
// 如果当前歌曲列表类型是下载歌曲列表
mCurrent = getNextCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ;
// 调用 getNextCurrent 方法,根据当前歌曲位置、播放模式和下载歌曲列表的大小计算下一首歌曲的位置
saveDownloadInfo ( mCurrent ) ;
saveDownloadInfo ( mCurrent ) ;
// 调用 saveDownloadInfo 方法, 将下载歌曲列表中当前位置( mCurrent) 的歌曲信息保存起来
}
}
if ( mListType ! = 0 ) mPlayStatusBinder . play ( mListType ) ;
if ( mListType ! = 0 ) mPlayStatusBinder . play ( mListType ) ;
}
// 如果 mListType 不为 0, 调用 mPlayStatusBinder 的 play 方法,根据当前列表类型开始播放歌曲
// 这意味着当列表类型有效时,会继续播放下一首歌曲,否则不进行播放操作
// 播放上一首歌曲
public void last ( ) {
public void last ( ) {
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ; //暂停广播
// 发送歌曲状态恢复事件,可能用于通知其他组件(如 UI 界面)歌曲状态将发生变化
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_RESUME ) ) ;
// 从 FileUtil 中获取当前歌曲的位置,并存储在 mCurrent 中
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
mCurrent = FileUtil . getSong ( ) . getPosition ( ) ;
// 根据播放模式获取上一首歌曲的索引并保存歌曲信息
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
if ( mListType = = Constant . LIST_TYPE_LOCAL ) {
// 如果是本地歌曲列表
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ;
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mLocalSongList . size ( ) ) ;
// 调用 getLastCurrent 方法,根据当前歌曲的位置、播放模式和本地歌曲列表的大小计算上一首歌曲的位置
// 不同的播放模式(如顺序、随机等)会影响计算结果
saveLocalSongInfo ( mCurrent ) ;
saveLocalSongInfo ( mCurrent ) ;
// 调用 saveLocalSongInfo 方法,将本地歌曲列表中对应上一首歌曲的信息保存起来
// 可能会保存歌曲的位置、名称、歌手、时长、URL 等信息
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
} else if ( mListType = = Constant . LIST_TYPE_ONLINE ) {
// 如果是在线歌曲列表
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ;
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mSongList . size ( ) ) ;
// 调用 getLastCurrent 方法,根据当前歌曲的位置、播放模式和在线歌曲列表的大小计算上一首歌曲的位置
saveOnlineSongInfo ( mCurrent ) ;
saveOnlineSongInfo ( mCurrent ) ;
// 调用 saveOnlineSongInfo 方法,将在线歌曲列表中对应上一首歌曲的信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
} else if ( mListType = = Constant . LIST_TYPE_LOVE ) {
// 如果是收藏歌曲列表
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ;
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mLoveList . size ( ) ) ;
// 调用 getLastCurrent 方法,根据当前歌曲的位置、播放模式和收藏歌曲列表的大小计算上一首歌曲的位置
saveLoveInfo ( mCurrent ) ;
saveLoveInfo ( mCurrent ) ;
// 调用 saveLoveInfo 方法,将收藏歌曲列表中对应上一首歌曲的信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
} else if ( mListType = = Constant . LIST_TYPE_HISTORY ) {
// 如果是历史歌曲列表
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ;
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mHistoryList . size ( ) ) ;
// 调用 getLastCurrent 方法,根据当前歌曲的位置、播放模式和历史歌曲列表的大小计算上一首歌曲的位置
saveHistoryInfo ( mCurrent ) ;
saveHistoryInfo ( mCurrent ) ;
// 调用 saveHistoryInfo 方法,将历史歌曲列表中对应上一首歌曲的信息保存起来
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
} else if ( mListType = = Constant . LIST_TYPE_DOWNLOAD ) {
// 如果是下载歌曲列表
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ;
mCurrent = getLastCurrent ( mCurrent , mPlayMode , mDownloadList . size ( ) ) ;
// 调用 getLastCurrent 方法,根据当前歌曲的位置、播放模式和下载歌曲列表的大小计算上一首歌曲的位置
saveDownloadInfo ( mCurrent ) ;
saveDownloadInfo ( mCurrent ) ;
// 调用 saveDownloadInfo 方法,将下载歌曲列表中对应上一首歌曲的信息保存起来
}
}
if ( mListType ! = 0 ) mPlayStatusBinder . play ( mListType ) ;
if ( mListType ! = 0 ) mPlayStatusBinder . play ( mListType ) ;
// 如果 mListType 不为 0, 调用 mPlayStatusBinder 的 play 方法,根据当前列表类型播放上一首歌曲
// 这样可以确保当列表类型有效时,会开始播放上一首歌曲
}
}
/ * *
// 停止音乐
* 停 止 音 乐
* /
public void stop ( ) {
public void stop ( ) {
// 检查 mediaPlayer 是否不为空
if ( mediaPlayer ! = null ) {
if ( mediaPlayer ! = null ) {
// 将 isPlaying 标志设置为 false, 表示音乐停止播放
isPlaying = false ;
isPlaying = false ;
// 调用 mediaPlayer 的 stop 方法停止播放音乐
mediaPlayer . stop ( ) ;
mediaPlayer . stop ( ) ;
try {
try {
mediaPlayer . prepare ( ) ; // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
// 调用 stop 后,如果要再次播放,需要调用 prepare 函数将 MediaPlayer 恢复到准备状态
mediaPlayer . prepare ( ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
// 打印异常堆栈信息
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
}
}
}
}
}
}
// 判断是否正在播放
public boolean isPlaying ( ) {
public boolean isPlaying ( ) {
// 返回 isPlaying 的值,用于外部判断当前是否正在播放音乐
return isPlaying ;
return isPlaying ;
}
}
// 获取媒体播放器对象
public MediaPlayer getMediaPlayer ( ) {
public MediaPlayer getMediaPlayer ( ) {
// 返回媒体播放器对象,以便外部对其进行操作
return mediaPlayer ;
return mediaPlayer ;
}
}
// 获取 PlayerService 实例
public PlayerService getPlayerService ( ) {
public PlayerService getPlayerService ( ) {
// 返回 PlayerService 自身的实例,可用于外部调用该服务的其他方法或访问其属性
return PlayerService . this ;
return PlayerService . this ;
}
}
// 获取当前播放时间(秒)
public long getCurrentTime ( ) {
public long getCurrentTime ( ) {
// 获取当前播放位置(毫秒),并将其转换为秒
return mediaPlayer . getCurrentPosition ( ) / 1000 ;
return mediaPlayer . getCurrentPosition ( ) / 1000 ;
}
}
}
}
@ -327,241 +434,370 @@ public class PlayerService extends Service {
@Override
@Override
public void onDestroy ( ) {
public void onDestroy ( ) {
// 输出日志,表明服务正在被销毁
Log . d ( TAG , "onDestroy: 服务被销毁了" ) ;
Log . d ( TAG , "onDestroy: 服务被销毁了" ) ;
if ( mediaPlayer ! = null ) {
if ( mediaPlayer ! = null ) {
// 停止媒体播放器
mediaPlayer . stop ( ) ;
mediaPlayer . stop ( ) ;
// 释放媒体播放器资源,避免资源泄漏
mediaPlayer . release ( ) ;
mediaPlayer . release ( ) ;
}
}
// 停止前台服务,隐藏通知等相关操作
stopForeground ( true ) ;
stopForeground ( true ) ;
}
}
@Override
@Override
public boolean onUnbind ( Intent intent ) {
public boolean onUnbind ( Intent intent ) {
// 输出日志,表明服务正在解绑
Log . d ( TAG , "onUnbind: jsyjst" ) ;
Log . d ( TAG , "onUnbind: jsyjst" ) ;
// 返回 true, 表示服务可以在所有客户端都解绑后自动销毁( 如果没有其他绑定)
return true ;
return true ;
}
}
// 保存本地音乐列表的信息
// 保存本地音乐列表的信息
private void saveLocalSongInfo ( int current ) {
private void saveLocalSongInfo ( int current ) {
//将歌曲的信息保存起来
// 从数据库中查找所有的 LocalSong 并存储在 mLocalSongList 中
mLocalSongList = LitePal . findAll ( LocalSong . class ) ;
mLocalSongList = LitePal . findAll ( LocalSong . class ) ;
// 创建一个新的 Song 对象
Song song = new Song ( ) ;
Song song = new Song ( ) ;
// 从 mLocalSongList 中根据当前索引获取 LocalSong 对象
LocalSong localSong = mLocalSongList . get ( current ) ;
LocalSong localSong = mLocalSongList . get ( current ) ;
// 设置 Song 对象的位置信息
song . setPosition ( current ) ;
song . setPosition ( current ) ;
// 设置 Song 对象的歌曲名称,从 localSong 中获取
song . setSongName ( localSong . getName ( ) ) ;
song . setSongName ( localSong . getName ( ) ) ;
// 设置 Song 对象的歌手信息,从 localSong 中获取
song . setSinger ( localSong . getSinger ( ) ) ;
song . setSinger ( localSong . getSinger ( ) ) ;
// 设置 Song 对象的歌曲时长,从 localSong 中获取
song . setDuration ( localSong . getDuration ( ) ) ;
song . setDuration ( localSong . getDuration ( ) ) ;
// 设置 Song 对象的歌曲 URL, 从 localSong 中获取
song . setUrl ( localSong . getUrl ( ) ) ;
song . setUrl ( localSong . getUrl ( ) ) ;
// 设置 Song 对象的图片 URL, 从 localSong 中获取
song . setImgUrl ( localSong . getPic ( ) ) ;
song . setImgUrl ( localSong . getPic ( ) ) ;
// 设置 Song 对象的歌曲 ID, 从 localSong 中获取
song . setSongId ( localSong . getSongId ( ) ) ;
song . setSongId ( localSong . getSongId ( ) ) ;
// 设置 Song 对象的 QQ 歌曲 ID, 从 localSong 中获取
song . setQqId ( localSong . getQqId ( ) ) ;
song . setQqId ( localSong . getQqId ( ) ) ;
// 设置 Song 对象为非在线歌曲
song . setOnline ( false ) ;
song . setOnline ( false ) ;
// 设置 Song 对象的列表类型为本地列表类型
song . setListType ( Constant . LIST_TYPE_LOCAL ) ;
song . setListType ( Constant . LIST_TYPE_LOCAL ) ;
// 使用 FileUtil 保存 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
// 保存网络专辑列表的信息
// 保存网络专辑列表的信息
private void saveOnlineSongInfo ( int current ) {
private void saveOnlineSongInfo ( int current ) {
// 从数据库中查找所有的 OnlineSong 并存储在 mSongList 中
mSongList = LitePal . findAll ( OnlineSong . class ) ;
mSongList = LitePal . findAll ( OnlineSong . class ) ;
// 创建一个新的 Song 对象
Song song = new Song ( ) ;
Song song = new Song ( ) ;
// 设置 Song 对象的位置信息
song . setPosition ( current ) ;
song . setPosition ( current ) ;
// 设置 Song 对象的歌曲 ID, 从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setSongId ( mSongList . get ( current ) . getSongId ( ) ) ;
song . setSongId ( mSongList . get ( current ) . getSongId ( ) ) ;
// 设置 Song 对象的歌曲名称,从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setSongName ( mSongList . get ( current ) . getName ( ) ) ;
song . setSongName ( mSongList . get ( current ) . getName ( ) ) ;
// 设置 Song 对象的歌手信息,从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setSinger ( mSongList . get ( current ) . getSinger ( ) ) ;
song . setSinger ( mSongList . get ( current ) . getSinger ( ) ) ;
// 设置 Song 对象的歌曲时长,从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setDuration ( mSongList . get ( current ) . getDuration ( ) ) ;
song . setDuration ( mSongList . get ( current ) . getDuration ( ) ) ;
// 设置 Song 对象的歌曲 URL, 从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setUrl ( mSongList . get ( current ) . getUrl ( ) ) ;
song . setUrl ( mSongList . get ( current ) . getUrl ( ) ) ;
// 设置 Song 对象的图片 URL, 从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setImgUrl ( mSongList . get ( current ) . getPic ( ) ) ;
song . setImgUrl ( mSongList . get ( current ) . getPic ( ) ) ;
// 设置 Song 对象为在线歌曲
song . setOnline ( true ) ;
song . setOnline ( true ) ;
// 设置 Song 对象的列表类型为在线列表类型
song . setListType ( Constant . LIST_TYPE_ONLINE ) ;
song . setListType ( Constant . LIST_TYPE_ONLINE ) ;
// 设置 Song 对象的媒体 ID, 从 mSongList 中根据当前索引获取的 OnlineSong 对象中获取
song . setMediaId ( mSongList . get ( current ) . getMediaId ( ) ) ;
song . setMediaId ( mSongList . get ( current ) . getMediaId ( ) ) ;
// 使用 FileUtil 保存 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
// 保存我的 收藏的 列表的信息
// 保存收藏列表的信息
private void saveLoveInfo ( int current ) {
private void saveLoveInfo ( int current ) {
// 从数据库中查找所有的 Love 并存储在 mLoveList 中,同时对列表进行排序
mLoveList = orderList ( LitePal . findAll ( Love . class ) ) ;
mLoveList = orderList ( LitePal . findAll ( Love . class ) ) ;
// 从 mLoveList 中根据当前索引获取 Love 对象
Love love = mLoveList . get ( current ) ;
Love love = mLoveList . get ( current ) ;
// 创建一个新的 Song 对象
Song song = new Song ( ) ;
Song song = new Song ( ) ;
// 设置 Song 对象的位置信息
song . setPosition ( current ) ;
song . setPosition ( current ) ;
// 设置 Song 对象的歌曲 ID, 从 love 中获取
song . setSongId ( love . getSongId ( ) ) ;
song . setSongId ( love . getSongId ( ) ) ;
// 设置 Song 对象的 QQ 歌曲 ID, 从 love 中获取
song . setQqId ( love . getQqId ( ) ) ;
song . setQqId ( love . getQqId ( ) ) ;
// 设置 Song 对象的歌曲名称,从 love 中获取
song . setSongName ( love . getName ( ) ) ;
song . setSongName ( love . getName ( ) ) ;
// 设置 Song 对象的歌手信息,从 love 中获取
song . setSinger ( love . getSinger ( ) ) ;
song . setSinger ( love . getSinger ( ) ) ;
// 设置 Song 对象的歌曲 URL, 从 love 中获取
song . setUrl ( love . getUrl ( ) ) ;
song . setUrl ( love . getUrl ( ) ) ;
// 设置 Song 对象的图片 URL, 从 love 中获取
song . setImgUrl ( love . getPic ( ) ) ;
song . setImgUrl ( love . getPic ( ) ) ;
// 设置 Song 对象的列表类型为收藏列表类型
song . setListType ( Constant . LIST_TYPE_LOVE ) ;
song . setListType ( Constant . LIST_TYPE_LOVE ) ;
// 设置 Song 对象的在线状态,从 love 中获取
song . setOnline ( love . isOnline ( ) ) ;
song . setOnline ( love . isOnline ( ) ) ;
// 设置 Song 对象的歌曲时长,从 love 中获取
song . setDuration ( love . getDuration ( ) ) ;
song . setDuration ( love . getDuration ( ) ) ;
// 设置 Song 对象的媒体 ID, 从 love 中获取
song . setMediaId ( love . getMediaId ( ) ) ;
song . setMediaId ( love . getMediaId ( ) ) ;
// 设置 Song 对象的下载状态,从 love 中获取
song . setDownload ( love . isDownload ( ) ) ;
song . setDownload ( love . isDownload ( ) ) ;
// 使用 FileUtil 保存 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
// 保存下载列表的信息
// 保存下载列表的信息
private void saveDownloadInfo ( int current ) {
private void saveDownloadInfo ( int current ) {
// 从 mDownloadList 中根据当前索引获取 DownloadSong 对象
DownloadSong downloadSong = mDownloadList . get ( current ) ;
DownloadSong downloadSong = mDownloadList . get ( current ) ;
// 创建一个新的 Song 对象
Song song = new Song ( ) ;
Song song = new Song ( ) ;
// 设置 Song 对象的位置信息
song . setPosition ( current ) ;
song . setPosition ( current ) ;
// 设置 Song 对象的歌曲 ID, 从 downloadSong 中获取
song . setSongId ( downloadSong . getSongId ( ) ) ;
song . setSongId ( downloadSong . getSongId ( ) ) ;
// 设置 Song 对象的歌曲名称,从 downloadSong 中获取
song . setSongName ( downloadSong . getName ( ) ) ;
song . setSongName ( downloadSong . getName ( ) ) ;
// 设置 Song 对象的歌手信息,从 downloadSong 中获取
song . setSinger ( downloadSong . getSinger ( ) ) ;
song . setSinger ( downloadSong . getSinger ( ) ) ;
// 设置 Song 对象的歌曲 URL, 从 downloadSong 中获取
song . setUrl ( downloadSong . getUrl ( ) ) ;
song . setUrl ( downloadSong . getUrl ( ) ) ;
// 设置 Song 对象的图片 URL, 从 downloadSong 中获取
song . setImgUrl ( downloadSong . getPic ( ) ) ;
song . setImgUrl ( downloadSong . getPic ( ) ) ;
// 设置 Song 对象的列表类型为下载列表类型
song . setListType ( Constant . LIST_TYPE_DOWNLOAD ) ;
song . setListType ( Constant . LIST_TYPE_DOWNLOAD ) ;
// 设置 Song 对象为非在线歌曲
song . setOnline ( false ) ;
song . setOnline ( false ) ;
// 设置 Song 对象的歌曲时长,从 downloadSong 中获取
song . setDuration ( downloadSong . getDuration ( ) ) ;
song . setDuration ( downloadSong . getDuration ( ) ) ;
// 设置 Song 对象的媒体 ID, 从 downloadSong 中获取
song . setMediaId ( downloadSong . getMediaId ( ) ) ;
song . setMediaId ( downloadSong . getMediaId ( ) ) ;
// 设置 Song 对象的下载状态为已下载
song . setDownload ( true ) ;
song . setDownload ( true ) ;
// 使用 FileUtil 保存 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
//保存我的收藏的 列表的信息
// 保存历史播放 列表的信息
private void saveHistoryInfo ( int current ) {
private void saveHistoryInfo ( int current ) {
// 从 mHistoryList 中根据当前索引获取 HistorySong 对象
HistorySong historySong = mHistoryList . get ( current ) ;
HistorySong historySong = mHistoryList . get ( current ) ;
// 创建一个新的 Song 对象
Song song = new Song ( ) ;
Song song = new Song ( ) ;
// 设置 Song 对象的位置信息
song . setPosition ( current ) ;
song . setPosition ( current ) ;
// 设置 Song 对象的歌曲 ID, 从 historySong 中获取
song . setSongId ( historySong . getSongId ( ) ) ;
song . setSongId ( historySong . getSongId ( ) ) ;
// 设置 Song 对象的 QQ 歌曲 ID, 从 historySong 中获取
song . setQqId ( historySong . getQqId ( ) ) ;
song . setQqId ( historySong . getQqId ( ) ) ;
// 设置 Song 对象的歌曲名称,从 historySong 中获取
song . setSongName ( historySong . getName ( ) ) ;
song . setSongName ( historySong . getName ( ) ) ;
// 设置 Song 对象的歌手信息,从 historySong 中获取
song . setSinger ( historySong . getSinger ( ) ) ;
song . setSinger ( historySong . getSinger ( ) ) ;
// 设置 Song 对象的歌曲 URL, 从 historySong 中获取
song . setUrl ( historySong . getUrl ( ) ) ;
song . setUrl ( historySong . getUrl ( ) ) ;
// 设置 Song 对象的图片 URL, 从 historySong 中获取
song . setImgUrl ( historySong . getPic ( ) ) ;
song . setImgUrl ( historySong . getPic ( ) ) ;
// 设置 Song 对象的列表类型为历史播放列表类型
song . setListType ( Constant . LIST_TYPE_HISTORY ) ;
song . setListType ( Constant . LIST_TYPE_HISTORY ) ;
// 设置 Song 对象的在线状态,从 historySong 中获取
song . setOnline ( historySong . isOnline ( ) ) ;
song . setOnline ( historySong . isOnline ( ) ) ;
// 设置 Song 对象的歌曲时长,从 historySong 中获取
song . setDuration ( historySong . getDuration ( ) ) ;
song . setDuration ( historySong . getDuration ( ) ) ;
// 设置 Song 对象的媒体 ID, 从 historySong 中获取
song . setMediaId ( historySong . getMediaId ( ) ) ;
song . setMediaId ( historySong . getMediaId ( ) ) ;
// 设置 Song 对象的下载状态,从 historySong 中获取
song . setDownload ( historySong . isDownload ( ) ) ;
song . setDownload ( historySong . isDownload ( ) ) ;
// 使用 FileUtil 保存 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
}
}
// 将歌曲保存到最近播放的数据库中
// 将歌曲保存到最近播放的数据库中
private void saveToHistoryTable ( ) {
private void saveToHistoryTable ( ) {
// 从 FileUtil 中获取当前的 Song 对象
final Song song = FileUtil . getSong ( ) ;
final Song song = FileUtil . getSong ( ) ;
// 使用 LitePal 异步查找 songId 匹配的 HistorySong 列表
LitePal . where ( "songId=?" , song . getSongId ( ) ) . findAsync ( HistorySong . class )
LitePal . where ( "songId=?" , song . getSongId ( ) ) . findAsync ( HistorySong . class )
. listen ( new FindMultiCallback < HistorySong > ( ) {
. listen ( new FindMultiCallback < HistorySong > ( ) {
@Override
@Override
public void onFinish ( List < HistorySong > list ) {
public void onFinish ( List < HistorySong > list ) {
// 如果找到的列表大小为 1, 表示该歌曲已经存在于历史播放列表中
if ( list . size ( ) = = 1 ) {
if ( list . size ( ) = = 1 ) {
// 删除已存在的历史记录,避免重复添加
LitePal . deleteAll ( HistorySong . class , "songId=?" , song . getSongId ( ) ) ;
LitePal . deleteAll ( HistorySong . class , "songId=?" , song . getSongId ( ) ) ;
}
}
// 创建一个新的 HistorySong 对象
final HistorySong history = new HistorySong ( ) ;
final HistorySong history = new HistorySong ( ) ;
// 设置 HistorySong 对象的歌曲 ID, 从 song 中获取
history . setSongId ( song . getSongId ( ) ) ;
history . setSongId ( song . getSongId ( ) ) ;
// 设置 HistorySong 对象的 QQ 歌曲 ID, 从 song 中获取
history . setQqId ( song . getQqId ( ) ) ;
history . setQqId ( song . getQqId ( ) ) ;
// 设置 HistorySong 对象的歌曲名称,从 song 中获取
history . setName ( song . getSongName ( ) ) ;
history . setName ( song . getSongName ( ) ) ;
// 设置 HistorySong 对象的歌手信息,从 song 中获取
history . setSinger ( song . getSinger ( ) ) ;
history . setSinger ( song . getSinger ( ) ) ;
// 设置 HistorySong 对象的歌曲 URL, 从 song 中获取
history . setUrl ( song . getUrl ( ) ) ;
history . setUrl ( song . getUrl ( ) ) ;
// 设置 HistorySong 对象的图片 URL, 从 song 中获取
history . setPic ( song . getImgUrl ( ) ) ;
history . setPic ( song . getImgUrl ( ) ) ;
// 设置 HistorySong 对象的在线状态,从 song 中获取
history . setOnline ( song . isOnline ( ) ) ;
history . setOnline ( song . isOnline ( ) ) ;
// 设置 HistorySong 对象的歌曲时长,从 song 中获取
history . setDuration ( song . getDuration ( ) ) ;
history . setDuration ( song . getDuration ( ) ) ;
// 设置 HistorySong 对象的媒体 ID, 从 song 中获取
history . setMediaId ( song . getMediaId ( ) ) ;
history . setMediaId ( song . getMediaId ( ) ) ;
// 设置 HistorySong 对象的下载状态,从 song 中获取
history . setDownload ( song . isDownload ( ) ) ;
history . setDownload ( song . isDownload ( ) ) ;
// 异步保存 HistorySong 对象
history . saveAsync ( ) . listen ( new SaveCallback ( ) {
history . saveAsync ( ) . listen ( new SaveCallback ( ) {
@Override
@Override
public void onFinish ( boolean success ) {
public void onFinish ( boolean success ) {
if ( success ) {
if ( success ) {
//告诉 主界面最近播放的数目需要改变
// 发送 SongListNumEvent 事件,通知 主界面最近播放的数目需要改变
EventBus . getDefault ( ) . post ( new SongListNumEvent ( Constant . LIST_TYPE_HISTORY ) ) ;
EventBus . getDefault ( ) . post ( new SongListNumEvent ( Constant . LIST_TYPE_HISTORY ) ) ;
// 如果历史播放列表的大小超过了最大历史记录数
if ( LitePal . findAll ( HistorySong . class ) . size ( ) > Constant . HISTORY_MAX_SIZE ) {
if ( LitePal . findAll ( HistorySong . class ) . size ( ) > Constant . HISTORY_MAX_SIZE ) {
// 删除最早的历史记录,保持列表长度不超过最大长度
LitePal . delete ( HistorySong . class , LitePal . findFirst ( HistorySong . class ) . getId ( ) ) ;
LitePal . delete ( HistorySong . class , LitePal . findFirst ( HistorySong . class ) . getId ( ) ) ;
}
}
}
}
}
}
} ) ;
} ) ;
}
}
} ) ;
} ) ;
}
}
// 对数据库进行倒叙 排序
// 对收藏列表进行倒序 排序
private List orderList ( List < Love > tempList ) {
private List orderList ( List < Love > tempList ) {
// 创建一个新的 Love 类型的列表 loveList
List < Love > loveList = new ArrayList < > ( ) ;
List < Love > loveList = new ArrayList < > ( ) ;
// 清空 loveList, 确保列表为空
loveList . clear ( ) ;
loveList . clear ( ) ;
// 从 tempList 的最后一个元素开始,依次将元素添加到 loveList 的开头,实现倒序排序
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
loveList . add ( tempList . get ( i ) ) ;
loveList . add ( tempList . get ( i ) ) ;
}
}
// 返回倒序排序后的 loveList
return loveList ;
return loveList ;
}
}
// 对下载列表进行倒序排序
private List < DownloadSong > orderDownloadList ( List < DownloadSong > tempList ) {
private List < DownloadSong > orderDownloadList ( List < DownloadSong > tempList ) {
// 创建一个新的 DownloadSong 类型的列表 downloadSongList
List < DownloadSong > downloadSongList = new ArrayList < > ( ) ;
List < DownloadSong > downloadSongList = new ArrayList < > ( ) ;
// 清空 downloadSongList, 确保列表为空
downloadSongList . clear ( ) ;
downloadSongList . clear ( ) ;
// 从 tempList 的最后一个元素开始,依次将元素添加到 downloadSongList 的开头,实现倒序排序
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
downloadSongList . add ( tempList . get ( i ) ) ;
downloadSongList . add ( tempList . get ( i ) ) ;
}
}
// 返回倒序排序后的 downloadSongList
return downloadSongList ;
return downloadSongList ;
}
}
// 对历史播放列表进行倒序排序
private List < HistorySong > orderHistoryList ( List < HistorySong > tempList ) {
private List < HistorySong > orderHistoryList ( List < HistorySong > tempList ) {
// 创建一个新的 HistorySong 类型的列表 historySongList
List < HistorySong > historySongList = new ArrayList < > ( ) ;
List < HistorySong > historySongList = new ArrayList < > ( ) ;
// 清空 historySongList, 确保列表为空
historySongList . clear ( ) ;
historySongList . clear ( ) ;
// 从 tempList 的最后一个元素开始,依次将元素添加到 historySongList 的开头,实现倒序排序
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
for ( int i = tempList . size ( ) - 1 ; i > = 0 ; i - - ) {
historySongList . add ( tempList . get ( i ) ) ;
historySongList . add ( tempList . get ( i ) ) ;
}
}
// 返回倒序排序后的 historySongList
return historySongList ;
return historySongList ;
}
}
// 网络请求获取播放地址
// 网络请求获取播放地址
private void getSongUrl ( String songId ) {
private void getSongUrl ( String songId ) {
// 打印日志,显示正在请求的歌曲的 ID 信息
Log . d ( TAG , "getSongUrl: " + Api . SONG_URL_DATA_LEFT + songId + Api . SONG_URL_DATA_RIGHT ) ;
Log . d ( TAG , "getSongUrl: " + Api . SONG_URL_DATA_LEFT + songId + Api . SONG_URL_DATA_RIGHT ) ;
// 使用 RetrofitFactory 创建一个网络请求,请求歌曲的播放地址
RetrofitFactory . createRequestOfSongUrl ( ) . 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 ( ) )
. subscribeOn ( Schedulers . io ( ) )
// 指定网络请求在 IO 线程执行
. observeOn ( AndroidSchedulers . mainThread ( ) )
// 指定结果处理在主线程执行
. subscribeWith ( new Observer < SongUrl > ( ) {
. subscribeWith ( new Observer < SongUrl > ( ) {
@Override
@Override
public void onSubscribe ( Disposable disposable ) {
public void onSubscribe ( Disposable disposable ) {
// 当订阅开始时,可进行一些初始化操作,但这里为空
}
}
@Override
@Override
public void onNext ( SongUrl songUrl ) {
public void onNext ( SongUrl songUrl ) {
// 当网络请求成功获取到 SongUrl 对象时
if ( songUrl . getCode ( ) = = 0 ) {
if ( songUrl . getCode ( ) = = 0 ) {
// 获取歌曲的 sip 和 purl 信息
String sip = songUrl . getReq_0 ( ) . getData ( ) . getSip ( ) . get ( 0 ) ;
String sip = songUrl . getReq_0 ( ) . getData ( ) . getSip ( ) . get ( 0 ) ;
String purl = songUrl . getReq_0 ( ) . getData ( ) . getMidurlinfo ( ) . get ( 0 ) . getPurl ( ) ;
String purl = songUrl . getReq_0 ( ) . getData ( ) . getMidurlinfo ( ) . get ( 0 ) . getPurl ( ) ;
// 如果 purl 为空,表示歌曲无版权
if ( purl . equals ( "" ) ) {
if ( purl . equals ( "" ) ) {
// 显示提示信息,让用户尝试搜索其他歌曲
CommonUtil . showToast ( PlayerService . this , "该歌曲暂时没有版权,试试搜索其它歌曲吧" ) ;
CommonUtil . showToast ( PlayerService . this , "该歌曲暂时没有版权,试试搜索其它歌曲吧" ) ;
return ;
return ;
}
}
// 从 FileUtil 中获取当前的 Song 对象
Song song = FileUtil . getSong ( ) ;
Song song = FileUtil . getSong ( ) ;
assert song ! = null ;
assert song ! = null ;
// 设置 Song 对象的 URL 为 sip + purl
song . setUrl ( sip + purl ) ;
song . setUrl ( sip + purl ) ;
// 保存更新后的 Song 对象
FileUtil . saveSong ( song ) ;
FileUtil . saveSong ( song ) ;
try {
try {
// 将媒体播放器的数据源设置为 sip + purl
mediaPlayer . setDataSource ( sip + purl ) ;
mediaPlayer . setDataSource ( sip + purl ) ;
// 打印日志,显示正在设置数据源
Log . d ( TAG , "onNext:jsyjst =" + sip + purl ) ;
Log . d ( TAG , "onNext:jsyjst =" + sip + purl ) ;
// 调用 startPlay 方法开始播放歌曲
startPlay ( ) ;
startPlay ( ) ;
} catch ( IOException e ) {
} catch ( IOException e ) {
// 打印异常信息
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
}
}
} else {
} else {
// 当获取的歌曲 URL 的 code 不为 0, 打印错误信息
Log . d ( TAG , "onNext:" + songUrl . getCode ( ) + ":获取不到歌曲播放地址" ) ;
Log . d ( TAG , "onNext:" + songUrl . getCode ( ) + ":获取不到歌曲播放地址" ) ;
}
}
}
}
@Override
@Override
public void onError ( Throwable throwable ) {
public void onError ( Throwable throwable ) {
// 当网络请求出现错误时,打印错误信息
Log . d ( TAG , "onError: " + throwable . toString ( ) ) ;
Log . d ( TAG , "onError: " + throwable . toString ( ) ) ;
}
}
@Override
@Override
public void onComplete ( ) {
public void onComplete ( ) {
// 当网络请求完成时,可进行一些清理或后续操作,但这里为空
}
}
} ) ;
} ) ;
}
}
// 开始播放
// 开始播放
private void startPlay ( ) throws IOException {
private void startPlay ( ) throws IOException {
mediaPlayer . prepare ( ) ; //进行缓冲
// 调用 mediaPlayer 的 prepare 方法,准备播放歌曲,可能会进行缓冲等操作
mediaPlayer . prepare ( ) ;
// 将 isPlaying 标记为 true, 表示正在播放
isPlaying = true ;
isPlaying = true ;
// 调用 mediaPlayer 的 start 方法,开始播放歌曲
mediaPlayer . start ( ) ;
mediaPlayer . start ( ) ;
// 调用 saveToHistoryTable 方法将歌曲信息保存到历史播放表
saveToHistoryTable ( ) ;
saveToHistoryTable ( ) ;
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_CHANGE ) ) ; //发送所有歌曲改变事件
// 发送 SongStatusEvent 事件,通知歌曲状态发生改变,可能用于更新 UI 等
EventBus . getDefault ( ) . post ( new OnlineSongChangeEvent ( ) ) ; //发送网络歌曲改变事件
EventBus . getDefault ( ) . post ( new SongStatusEvent ( Constant . SONG_CHANGE ) ) ;
//改变通知栏歌曲
// 发送 OnlineSongChangeEvent 事件,可能用于更新在线歌曲相关的 UI 或逻辑
EventBus . getDefault ( ) . post ( new OnlineSongChangeEvent ( ) ) ;
// 从 FileUtil 中获取当前歌曲对象
Song song = FileUtil . getSong ( ) ;
Song song = FileUtil . getSong ( ) ;
// 获取通知管理器并更新通知,使用歌曲的名称和歌手信息更新通知栏
getNotificationManager ( ) . notify ( NOTIFICATION_ID ,
getNotificationManager ( ) . notify ( NOTIFICATION_ID ,
getNotification ( song . getSongName ( ) + " - " + song . getSinger ( ) ) ) ;
getNotification ( song . getSongName ( ) + " - " + song . getSinger ( ) ) ) ;
}
}
@ -570,61 +806,81 @@ public class PlayerService extends Service {
// 根据播放模式得到下一首歌曲的位置
// 根据播放模式得到下一首歌曲的位置
private int getNextCurrent ( int current , int playMode , int len ) {
private int getNextCurrent ( int current , int playMode , int len ) {
int res ;
int res ;
// 如果是顺序播放模式
if ( playMode = = Constant . PLAY_ORDER ) {
if ( playMode = = Constant . PLAY_ORDER ) {
// 下一首歌曲的位置是当前位置加 1 对列表长度取模,实现循环播放
res = ( current + 1 ) % len ;
res = ( current + 1 ) % len ;
} else if ( playMode = = Constant . PLAY_RANDOM ) {
} else if ( playMode = = Constant . PLAY_RANDOM ) {
// 如果是随机播放模式
// 生成一个随机数乘以列表长度并取模,得到随机位置
res = ( current + ( int ) ( Math . random ( ) * len ) ) % len ;
res = ( current + ( int ) ( Math . random ( ) * len ) ) % len ;
} else {
} else {
// 否则(可能是单曲循环等模式),位置不变
res = current ;
res = current ;
}
}
return res ;
return res ;
}
}
// 根据播放模式得到上一首歌曲的位置
// 根据播放模式得到上一首歌曲的位置
private int getLastCurrent ( int current , int playMode , int len ) {
private int getLastCurrent ( int current , int playMode , int len ) {
int res ;
int res ;
// 如果是顺序播放模式
if ( playMode = = Constant . PLAY_ORDER ) {
if ( playMode = = Constant . PLAY_ORDER ) {
// 上一首歌曲的位置是当前位置减 1, 如果减到 -1 则为列表的最后一个元素,实现循环播放
res = current - 1 = = - 1 ? len - 1 : current - 1 ;
res = current - 1 = = - 1 ? len - 1 : current - 1 ;
} else if ( playMode = = Constant . PLAY_RANDOM ) {
} else if ( playMode = = Constant . PLAY_RANDOM ) {
// 如果是随机播放模式
// 生成一个随机数乘以列表长度并取模,得到随机位置
res = ( current + ( int ) ( Math . random ( ) * len ) ) % len ;
res = ( current + ( int ) ( Math . random ( ) * len ) ) % len ;
} else {
} else {
// 否则(可能是单曲循环等模式),位置不变
res = current ;
res = current ;
}
}
return res ;
return res ;
}
}
//开启前台服务
// 获取通知管理器
private NotificationManager getNotificationManager ( ) {
private NotificationManager getNotificationManager ( ) {
// 调用 getSystemService 方法获取系统的通知管理器
return ( NotificationManager ) getSystemService ( NOTIFICATION_SERVICE ) ;
return ( NotificationManager ) getSystemService ( NOTIFICATION_SERVICE ) ;
}
}
// 设置通知栏标题
// 设置通知栏标题
private Notification getNotification ( String title ) {
private Notification getNotification ( String title ) {
// 创建一个 Intent, 点击通知时跳转到 MainActivity
Intent intent = new Intent ( this , MainActivity . class ) ;
Intent intent = new Intent ( this , MainActivity . class ) ;
// 创建一个 PendingIntent, 用于点击通知时启动 MainActivity
PendingIntent pi = PendingIntent . getActivity ( this , 0 , intent , 0 ) ;
PendingIntent pi = PendingIntent . getActivity ( this , 0 , intent , 0 ) ;
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . O ) {
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . O ) {
String id = "play" ;
String id = "play" ;
String name = "播放歌曲" ;
String name = "播放歌曲" ;
// 创建一个通知通道,适用于 Android 8.0 及以上版本
NotificationChannel mChannel = new NotificationChannel ( id , name , NotificationManager . IMPORTANCE_LOW ) ;
NotificationChannel mChannel = new NotificationChannel ( id , name , NotificationManager . IMPORTANCE_LOW ) ;
// 在通知管理器中创建通知通道
getNotificationManager ( ) . createNotificationChannel ( mChannel ) ;
getNotificationManager ( ) . createNotificationChannel ( mChannel ) ;
// 创建一个通知构建器
Notification . Builder builder = new Notification . Builder ( this , id ) ;
Notification . Builder builder = new Notification . Builder ( this , id ) ;
// 设置通知的小图标
builder . setSmallIcon ( R . mipmap . icon ) ;
builder . setSmallIcon ( R . mipmap . icon ) ;
// 设置点击通知的 PendingIntent
builder . setContentIntent ( pi ) ;
builder . setContentIntent ( pi ) ;
// 设置通知的标题
builder . setContentTitle ( title ) ;
builder . setContentTitle ( title ) ;
// 构建并返回通知对象
return builder . build ( ) ;
return builder . build ( ) ;
} else {
} else {
// 对于 Android 8.0 以下版本,使用 NotificationCompat.Builder 创建通知
NotificationCompat . Builder builder = new NotificationCompat . Builder ( this , "play" ) ;
NotificationCompat . Builder builder = new NotificationCompat . Builder ( this , "play" ) ;
// 设置通知的小图标
builder . setSmallIcon ( R . mipmap . icon ) ;
builder . setSmallIcon ( R . mipmap . icon ) ;
// 设置通知的大图标
builder . setLargeIcon ( BitmapFactory . decodeResource ( getResources ( ) , R . mipmap . icon ) ) ;
builder . setLargeIcon ( BitmapFactory . decodeResource ( getResources ( ) , R . mipmap . icon ) ) ;
// 设置点击通知的 PendingIntent
builder . setContentIntent ( pi ) ;
builder . setContentIntent ( pi ) ;
// 设置通知的标题
builder . setContentTitle ( title ) ;
builder . setContentTitle ( title ) ;
// 构建并返回通知对象
return builder . build ( ) ;
return builder . build ( ) ;
}
}
}
}
}