欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发中后台播放音乐(Service方式)功能实现方法

程序员文章站 2022-06-23 11:59:52
Android实现后台播放音乐(Service方式) 先导android四大组件之Service知识可以参考博客: https://blog.csdn.net/weixin_3...

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方法

点击播放下一首,前一首,以及进度设置待完善…