前言:
本篇文章是个人学习日记,纯粹学习交流,如有错误或不到位的地方,请见谅。
之前我写了一个音乐播放器,回头看发现代码实在凌乱不堪,冗余.....
我决定重新编写一次简单,清晰的版本
以下说说怎么在Service使用Mediaplayer,以及控制播放停止及获取状态等信息。
贴代码,然后作解释
public class MyService extends Service {
private MediaPlayer mediaPlayer;
private MusicBinder musicBinder;
private boolean isSetData; //是否设置资源
//播放模式
public static final int SINGLE_CYCLE = 1; //单曲循环
public static final int ALL_CYCLE = 2; //全部循环
public static final int RANDOM_PLAY = 3; //随机播放
private int MODE;
@Override
public void onCreate() {
super.onCreate();
//初始化数据
isSetData = false;
MODE = ALL_CYCLE;
mediaPlayer = new MediaPlayer();
musicBinder = new MusicBinder();
}
private void playMusic(String path) {
try {
//设置资源
mediaPlayer.reset();
mediaPlayer.setDataSource(path);
isSetData = true;
//异步缓冲准备及监听
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
//播放结束监听
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
switch (MODE) {
case SINGLE_CYCLE:
//单曲循环
mediaPlayer.start();
break;
case ALL_CYCLE:
//全部循环
isSetData = false;
playNextSong(); //调用MainActivity的 playNextSong方法
break;
case RANDOM_PLAY:
//随机播放
isSetData = false;
playRandomSong(); //这里也是MainActivity的方法
break;
default:
}
}
});
} catch (Exception e) {
e.printStackTrace();
isSetData = false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
isSetData = false;
}
class MusicBinder extends Binder {
//开始播放
void start(String songUrl){
playMusic(songUrl);
}
//获取资源状态
boolean isSetData(){
return isSetData;
}
//获取当前播放状态
boolean isPlaying(){
return mediaPlayer.isPlaying();
}
//继续播放
boolean play(){
if (isSetData) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
}
return mediaPlayer.isPlaying();
}
//暂停播放
boolean pause(){
if (isSetData) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
return mediaPlayer.isPlaying();
}
/**
* 获取歌曲当前时长位置
* 如果返回-1,则mediaplayer没有缓冲歌曲
* @return
*/
int getCurrent(){
if (isSetData) {
return mediaPlayer.getCurrentPosition();
} else {
return -1;
}
}
/**
* 获取歌曲总时长
* 如果返回-1,则mediaplayer没有缓冲歌曲
* @return
*/
int getDuration(){
if (isSetData) {
return mediaPlayer.getDuration();
} else {
return -1;
}
}
//获取当前播放模式
int getMode(){
return MODE;
}
/**
* 更换播放模式
* 单曲循环 → 全部循环 → 随机播放 → 单曲循环
*/
int changeMode(){
switch (MODE) {
case SINGLE_CYCLE:
MODE = ALL_CYCLE;
break;
case ALL_CYCLE:
MODE = RANDOM_PLAY;
break;
case RANDOM_PLAY:
MODE = SINGLE_CYCLE;
break;
default:
}
return MODE;
}
}
@Override
public IBinder onBind(Intent intent) {
return musicBinder;
}
}
首先,声明一些变量,类
其中有Mediaplayer 和 自定义的MusicBinder 类
然后在 onCreate() 中初始化。
要在onDestory()中 释放mediaplayer相关资源
最主要就是 playMusic(String path) 和 MusicBinder的各种方法
一、playMusic(String path)
第一步:根据path来设置资源
第二步:我怕堵塞线程,因为有些一个小时的DJ音乐文件应用可能就崩溃了,所以使用异步准备
里面设有异步准备结束的监听,直接就mediaplayer.start();
第三步:就是播放结束的监听事件,根据当前MODE来选择播放
其中全部循环和随机播放都是调用MainActivity的方法
因为歌曲列表不在Service中,所以要去MainActivity中根据歌曲列表来选择播放
二、MusicBinder
操作类:start(String songUrl); play(); pause(); changeMode();
状态类:isSetData(); isPlaying() ; getMode(); getCurrent(); getDuration();
这么多方法,应该足够了。
附上MainActivty的 循环播放和随机播放的方法
public static void playNextSong() {
if (position == list.size() - 1) {
position = 0;
} else {
position++;
}
String songUrl = list.get(position).getUrl();
musicBinder.start(songUrl);
//做一些更新UI界面的操作
//例如 改变歌曲信息,控件状态
}
public static void playRandomSong(){
Random random = new Random();
position = random.nextInt(list.size());
String songUrl = list.get(position).getUrl();
musicBinder.start(songUrl);
//做一些更新UI界面的操作
//例如 改变歌曲信息,控件状态
}
其中position初始化是0,如果是直接点击列表的话,可以通过Adapter来确定position再传递给MainActivity的position