音频资源的抢占申请OnAudioFocusChangeListener 和AudioFocus
在做音乐播放器的时候外面一般需要写一个监听器来监听音频资源是否被抢占的监听器,比如当我们播放音乐的时候打开视频播放器播放视频这时候外面就要求音乐暂停然后播放视频。一般外面需要写一个音频变化的监听器:OnAudioFocusChangeListener。当其他的应用申请音频资源的方式不同时候我们做出相应的处理。
废话不多说,一个简单的监听器:focusChange表示的是音频改变的模式,即抢占资源的应用的申请音频的方式,这里监听到音频的变化时候可以直接放送消息利用handler异步处理播放器控件的状态和关闭播放器等操作,当用来修改notification的状态的时候,这时候可能播放器资源被回收(这取决于申请资源focusChange的方式),不能用notification.notify,得重新创建notification了。
private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if(focusChange == AudioManager.AUDIOFOCUS_GAIN ) { ... } else if (focusChange =..) { ... } } };
关于focusChange的介绍:(参考这篇博客:http://blog.csdn.net/thl789/article/details/7422931)
- AUDIOFOCUS_GAIN:获得了Audio Focus;
- AUDIOFOCUS_LOSS:失去了Audio Focus,并将会持续很长的时间。这里因为可能会停掉很长时间,所以不仅仅要停止Audio的播放,最好直接释放掉Media资源。而因为停止播放Audio的时间会很长,如果程序因为这个原因而失去AudioFocus,最好不要让它再次自动获得AudioFocus而继续播放,不然突然冒出来的声音会让用户感觉莫名其妙,感受很不好。这里直接放弃AudioFocus,当然也不用再侦听远程播放控制【如下面代码的处理】。要再次播放,除非用户再在界面上点击开始播放,才重新初始化Media,进行播放。
- AUDIOFOCUS_LOSS_TRANSIENT:暂时失去Audio Focus,并会很快再次获得。必须停止Audio的播放,但是因为可能会很快再次获得AudioFocus,这里可以不释放Media资源;
-
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
:暂时失去AudioFocus,但是可以继续播放,不过要在降低音量。
一、AudioFocus的申请与释放
获取/放弃AudioFocus的方法都在android.media.AudioManager中,获取AudioFocus用requestAudioFocus()
;用完之后,放弃AudioFocus,用abandonAudioFocus()
。
函数原型:
1、audioManager.requestAudioFocus(OnAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
streamType是《Android中的Audio播放:音量和远程播放控制》中说明的AudioStream,其值取决于AudioManager中的STREAM_xxx,在AudioStream的裁决机制中并未有什么实际意义;
- durationHint是持续性的指示:(这个值对应于第三个OnAudioFocusChangeListener中focusChange的方式即值)
AUDIOFOCUS_GAIN
指示申请得到的Audio Focus不知道会持续多久,一般是长期占有;
AUDIOFOCUS_GAIN_TRANSIENT
指示要申请的AudioFocus是暂时性的,会很快用完释放的;
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK不但说要申请的AudioFocus是暂时性的,还指示当前正在使用AudioFocus的可以继续播放,只是要“duck”一下(降低音量)。
AudioManager.OnAudioFocusChangeListener是申请成功之后监听AudioFocus使用情况的Listener,后续如果有别的程序要竞争AudioFocus,都是通过这个Listener的onAudioFocusChange()方法来通知这个Audio Focus的使用者的。
- AUDIOFOCUS_REQUEST_GRANTED:申请成功;
- AUDIOFOCUS_REQUEST_FAILED:申请失败。
2、 audioManager.abandonAudioFocus(OnAudioFocusChangeListener);