Android实现后台播放音乐(Service方式)

版权声明:本博客仅用于学习交流,欢迎转载,但请注明作者和出处 https://blog.csdn.net/weixin_37577039/article/details/78775931

Android实现后台播放音乐(Service方式)

先导android四大组件之Service知识可以参考博客:
http://blog.csdn.net/weixin_37577039/article/details/78495357

实现:

在res文件夹下添加raw文件夹,添加mp3/4格式的音乐文件

注意命名规则只能是a-z,0-9,和下划线_ 不能大写字母和-


AndroidManifest.xml中

 <service
     android:name=".MusicService"
     android:exported="false" >
 </service>

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;
    }

返回值可以参考博客:http://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) {
            }
        }
    };

音量相关:

通过AudioManager

AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);

1 获取最大媒体音量

 int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

2 获取当前音量

 int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

3 渐进式调节音量

adjustStreamVolume (int  streamType, int direction, int flags)

4 步进式调节:(直接调到那个音量):

setStreamVolume (int streamType, int index, int flags)

int streamType 需要调整的音量类型
(以下常量定义于AudioManager类中)

STREAM_ALARM 警报
STREAM_MUSIC 音乐回放即媒体音量              
STREAM_NOTIFICATION 窗口顶部状态栏Notification,
STREAM_RING 铃声        
STREAM_SYSTEM 系统        
STREAM_VOICE_CALL 通话

int direction 调整的方向,加或者减。(以下常量定义于AudioManager类中)

ADJUST_LOWER 降低音量
ADJUST_RAISE 升高音量            
ADJUST_SAME 保持不变,这个主要用于向用户展示当前的音量

int flags 附加的一些参数

FLAG_PLAY_SOUND 调整音量时播放声音
FLAG_SHOW_UI 调整时显示音量条,就是按音量键出现的那个
0表示什么也没有

int index:
把音量调整到index值


报错: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方法


猜你喜欢

转载自blog.csdn.net/weixin_37577039/article/details/78775931
今日推荐