获取音频焦点
我们知道,一款手机可能会有多个应用去播放音频,(手机安装多款音视频播放器这个是很常见的现象、同时打开多个音视频播放器也是很正常的)。
试想如果不有效的处理应用的音频,会出现什么情况?我们在听歌的同时可能还会听到啪啪啪的声音。(注:这里的啪啪啪指观看羽毛球视频)为了防止多个音乐播放应用同时播放音频,谷歌技术团队使用音频焦点(Audio Focus)来控制音频的播放。也就是,当且仅当apk获取到音频焦点成功以后,才可以播放音频!
通过( AudioManager 类 )这个方法获取音频焦点
public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
来获取音频焦点,这个方法有三个参数,下面仔细分析下这三个参数
参数一:OnAudioFocusChangeListener(音频焦点发生改变时候的监听),这个 OnAudioFocusChangeListener 是 AudioManager 的一个内部接口,本质是监听 音频焦点的状态。
比如,是否获取了焦点、焦点是否失去、焦点暂时失去等状态 ,通过源码可以得知,它有四种状态,分别是:
- 状态一:AudioManager.AUDIOFOCUS_GAIN
- 状态二:AudioManager.AUDIOFOCUS_LOSS
- 状态三:AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
- 状态四:AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
以上四种状态分别代表的意思如下:
- 状态一:即应用获取了焦点,获取了焦点即正常播放音频
- 状态二:即应用彻底失去了焦点,不能播放音频
- 状态三:即应用暂时失去焦点(比如我们按下 HOME 键、电源键等)
- 状态四:应用暂时失去焦点,但是这个 DUCK(DUCK翻译:鸭子、闪避、躲避)状态比较特殊,这种状态意味着其它应用可以继续播放,仅仅是在这一刻降低自己应用的音量,直到重新获取到音频焦点后恢复正常音量。应用场景有,比如在播放音乐的时候突然出现一个短暂的短信提示声音,仅仅是把歌曲的音量暂时调低,使得用户能够听到短信提示声,在此之后便立马恢复正常播放;再比如语言导航等等
注意:一旦结束了播放,需要确保调用 abandonAudioFocus()方法。也就是告知系统我们不再需要获取焦点且注销 AudioManager.OnAudioFocusChangeListener 监听器。
参数二:streamType(流类型)这个上面也说了,一般设置为 STREAM_MUSIC
参数三:durationHint (持续时间) 根据源码得知有以下几种固定写法:
- AUDIOFOCUS_GAIN_TRANSIENT 焦点请求是临时
- AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 如果它的音频输出被暂停,那么之前成功获取焦点的就可以继续播放
- AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 临时的(语音备忘记录或语音识别)
- AUDIOFOCUS_GAIN 也就是焦点请求(这个用的较多)
另外源码可以得知,这个获取音频焦点的返回值只有两种:
- 一种是:AUDIOFOCUS_REQUEST_FAILED = 0
- 一种是:AUDIOFOCUS_REQUEST_GRANTED = 1,其中,AUDIOFOCUS_REQUEST_GRANTED 代表的就是获取音频焦点成功