Android开发中后台播放音乐(Service方式)功能实现方法
Android实现后台播放音乐(Service方式)
先导android四大组件之Service知识可以参考博客:
https://blog.csdn.net/weixin_37577039/article/details/78495357
实现:
在res文件夹下添加raw文件夹,添加mp3/4格式的音乐文件
注意命名规则只能是a-z,0-9,和下划线_ 不能大写字母和-
AndroidManifest.xml中
android:exported是否支持其它应用调用当前组件
新建一个MusicService类继承Service并且implements MediaPlayer.OnCompletionListener监听播放完成事件
重写service的onCreate()方法
private MediaPlayer mediaPlayer; //Service初始化时调用 public void onCreate(){ super.onCreate(); //初始化时就创建一个MediaPlayer进行资源链接 mediaPlayer = MediaPlayer.create(this, R.raw.floating_clound); mediaPlayer.setOnCompletionListener(this); }
若只是想简单的进行后台播放
重写onStartCommand 方法
@Override public int onStartCommand (Intent intent,int flag, int startId) { // TODO Auto-generated method stub super.onStartCommand(intent,flag,startId); if(!mediaPlayer.isPlaying()){ // 开始播放 mediaPlayer.start(); // 允许循环播放 mediaPlayer.setLooping(true); } return START_STICKY; }
返回值可以参考博客:https://blog.csdn.net/weixin_37577039/article/details/78495357
若想进行绑定
@Override public IBinder onBind(Intent intent) { if(!mediaPlayer.isPlaying()){ // 开始播放 mediaPlayer.start(); // 允许循环播放 mediaPlayer.setLooping(true); } return binder; }
解除绑定
@Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub //松绑Service,会触发onDestroy() if(mediaPlayer.isPlaying()){ mediaPlayer.stop(); } return super.onUnbind(intent); }
重写Ondestroy方法
@Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); //先停止 再释放 if(mediaPlayer.isPlaying()){ mediaPlayer.stop(); } mediaPlayer.release(); }
当Audio播放完的时候触发该动作
/** * 当Audio播放完的时候触发该动作 */ @Override public void onCompletion(MediaPlayer player) { // TODO Auto-generated method stub // 结束Service stopSelf(); }
并且写一个类继承Binder
class MyMusicBinder extends Binder{ //返回Service对象 MusicService getService(){ return MusicService.this; } }
在Activity中:
// 创建自定义的音乐Service对象 private MusicService musicService;
在Activity中创建一个private connector类 (连接服务的Client)监听Service状态的变化
private class MusicConnector implements ServiceConnection { //成功绑定时调用 即bindService()执行成功同时返回非空Ibinder对象 @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { musicService = ((MusicService.MyMusicBinder) iBinder).getService(); } //不成功绑定时调用 @Override public void onServiceDisconnected(ComponentName componentName) { musicService = null; Log.i("binding is fail", "binding is fail"); } }
在点击事件中:(点击播放和暂停按钮)
private View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { Button btn = (Button) v; try { Intent intent = new Intent(); intent.setClass(MainActivity.this, MusicService.class); switch (btn.getId()) { case R.id.play: { conn= new MusicConnector(); bindService(intent, conn, Context.BIND_AUTO_CREATE); break; } case R.id.pause: { //结束Service unbindService(conn); break; } } } catch (Exception e) { } } };
报错:leaked ServiceConnection
在Activity关闭的时候,没有去关闭Service
解决: 在onDestroy() 方法中解除service的绑定(binding模式)或者stopService(非binding模式)
@Override public void onDestroy(){ super.onDestroy(); unbindService(conn); }
问题: 暂停音乐再重新播放会重头开始
因为调用onbind又执行了onDestroy
具体的启动情况有下:
1.当启动时,单独调用bindService方法,在unbindService后,会执行service的onUnbind,再执行onDestroy方法。
2.当启动时,先调用startService,再调用bindService方法后,在unbindService后,会执行service的onUnbind,不会执行onDestroy方法。除非你在执行stopService.
3. 先调用startService,在调用stopService,会执行service的onDestroy方法
点击播放下一首,前一首,以及进度设置待完善…