以下记录用 Service + MediaPlayer 实现网络音频文件的播放
1. Service 的实现
public class MusicPlayerService extends Service
implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener {
private String TAG = "Music-->log--> MusicPlayerService";
//当前正在工作的播放器对象
private MediaPlayer mMediaPlayer;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: intent " + intent + " flags " + flags + " startId " + startId);
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: intent " + intent);
//设置代理,所有播放相关的操作通过代理暴露给Avtivity
MusicPlayerBinder musicPlayerBinder = new MusicPlayerBinder(MusicPlayerService.this);
prepareMusic();
return musicPlayerBinder;
}
/**
* 准备MediaPlayer环境
*/
private void prepareMusic() {
try {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //设置音频流的类型。
mMediaPlayer.setOnPreparedListener(this); // 准备好
mMediaPlayer.setOnCompletionListener(this); //播放完成事件监听器
mMediaPlayer.setOnBufferingUpdateListener(this); //缓冲变化
mMediaPlayer.setOnErrorListener(this); //出错
mMediaPlayer.setOnInfoListener(this); //音频信息
mMediaPlayer.setWakeMode(MusicPlayerService.this, PowerManager.PARTIAL_WAKE_LOCK); //为MediaPlayer设置低级电源管理行为
Class<MediaPlayer> clazz = MediaPlayer.class;
Method method = clazz.getDeclaredMethod("setDataSource", String.class, Map.class);
String path = "http://mp3.9ku.com/hot/2007/11-01/91161.mp3"; //音乐文件
Log.e(TAG, "playMusic: startPlay-->: ID: ,PATH:" + path);
method.invoke(mMediaPlayer, path, null);
mMediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 暴露给代理Binder的 开始播放 的方法
*/
public void startMusic() {
Log.d(TAG, "startMusic: ");
mMediaPlayer.start();
}
/**
* 暴露给代理Binder的 停止播放
*/
public void stopMusic() {
mMediaPlayer.stop();
}
/**
* 暴露给代理Binder的 暂停播放
*/
public void pause() {
Log.d(TAG, "pause: ");
mMediaPlayer.pause();
}
/**
* MediaPlayer 初始化完成
*
* @param mediaPlayer
*/
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "onPrepared: MediaPlayer 初始化完成 ");
}
/**
* 缓冲百分比
*/
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "onBufferingUpdate: mp " + mp + " percent " + percent);
}
/**
* 播放完成调用
*/
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "onCompletion: mp " + mp);
}
/**
* 播放失败
*/
@Override
public boolean onError(MediaPlayer mp, int event, int extra) {
Log.d(TAG, "onError: mp " + mp + " extra " + extra + " event " + event);
return false;
}
/**
* 获取音频信息
*/
@Override
public boolean onInfo(MediaPlayer mp, int event, int extra) {
Log.d(TAG, "onInfo: mp " + mp + " event " + event + " extra " + extra);
return false;
}
/**
* 与Activity解除绑定,即Activity销毁时回调的生命周期方法
*/
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind: intent " + intent);
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: ");
super.onDestroy();
}
}
2.代理类,将所有播放相关的暴露给Activity
public class MusicPlayerBinder extends Binder {
private final MusicPlayerService mService;
public MusicPlayerBinder(MusicPlayerService musicPlayerService) {
this.mService = musicPlayerService;
}
public void startMusic() {
mService.startMusic();
}
public void stopMusic() {
mService.stopMusic();
}
public void pause() {
mService.pause();
}
}
3.Activity 绑定Service,操作音频文件
public class MusicPlayerActivity extends AppCompatActivity implements View.OnClickListener {
private String TAG = "Music-->log--> MusicPlayerActivity";
private MusicPlayerBinder mBinder;
private MusicPlayerServiceConnection mConnection;
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
unbindService(mConnection);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
initViews();
openService();
}
private void initViews() {
Button btnStart = findViewById(R.id.music_btn_start);
Button btnPause = findViewById(R.id.music_btn_pause);
btnStart.setOnClickListener(this);
btnPause.setOnClickListener(this);
}
/**
* 采用两种方式与Service建立连接
* startService :使Service长期在后台存在,不受Activity生命周期的影响
* bindService :使Activity能拿到Service的代理对象,能对Service进行操作
*/
private void openService() {
Intent intent = new Intent(this, MusicPlayerService.class);
startService(intent);
mConnection = new MusicPlayerServiceConnection();
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.music_btn_start) {
mBinder.startMusic(); //播放音乐
} else if (i == R.id.music_btn_pause) {
mBinder.pause(); // //暂停播放
}
}
/**
* Service绑定成功后的监听
* MusicPlayer Service Connection
*/
private class MusicPlayerServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected: ");
if (null != service) {
if (service instanceof MusicPlayerBinder) {
mBinder = (MusicPlayerBinder) service;
Log.d(TAG, "onServiceConnected: mBinder " + mBinder);
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
4.注意
1.权限
<uses-permission android:name="android.permission.INTERNET" /> <!-- 系统锁的机制, 只要有人拿着这个锁,系统就无法进入休 Service播放音乐,需要此权限--> <uses-permission android:name="android.permission.WAKE_LOCK" />2.Android9.0手机不做htts校验
参考