Gain/Loss:长期的持有、丢失音频焦点,比如:音乐场景;
Gain Transient/Loss Transient:短暂的持有、丢弃焦点,比如:闹钟、通话;
Gain Transient May Duck/Loss Transient Can Duck:短暂的持有、丢弃焦点,但是其他应用可以降低音量播放,比如:系统通知;车载导航。
Gain Transient Exclusive:短暂的持有焦点,但是是排他的,比如:录音。
其实AudioFocus的状态是对应的。当后一个应用去GainAudioFocus时,前一个应用就相对应地LossAudioFocus。后一个应用以什么形式去Gain,前一个应该就会受到相应Loss的通知。但是,当前一个应用收到这个Loss通知时,应用怎么处理是应用内部的事情。因为AudioFoucs机制是一个建议性而不是强制性的机制。应用使用这种机制只是使用户体验更加好,而不采用这套机制,甚至不遵循这套机制,对应用与系统本身来是,是没有什么影响的。
4、audiofocus机制就是一个栈机制。
(1)音频焦点是使用堆栈方式管理的,可以有多个应用同时存在于堆栈中,栈顶的元素持有音频焦点
如上图所示,AudioFocus机制是以栈的形式实现,位于栈顶的应用能获取到AudioFocus从而能输出音频。非栈顶应用会暂时失去AudioFocus直至位于其上面的全部应用关闭或主动丢失AudioFocus。
这个的第二个图C、B、A,表示暂时失去了焦点,app会收到:
case AUDIOFOCUS_LOSS_TRANSIENT:
case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
对应图3的B如果app收到case AUDIOFOCUS_LOSS: 表示audiofocus被长期夺走,当前的app需要stop->abandon();
对应图4的C,如果app收到case AUDIOFOCUS_GAIN::表示audiofocus被归还了,app重新可以播放了。
private onAudioFocusChangeListener mAudioFocusListener = newOnAudioFocusChangeListener(){
//当AudioFocus发生变化时,这个函数将会被调用。其中参数focusChange指示发生了什么变化
public void onAudioFocusChange(int focusChange){
switch( focusChange) {
/*AudioFocus被长期夺走,需要中止播放,并释放AudioFocus,这种情况对应于
抢走AudioFocus的申请者使用了AUDIOFOCUS_GAIN*/
case AUDIOFOCUS_LOSS:
stop();
break;
/*AudioFocus被临时夺走,不久就会被归还,只需要暂停,AudioFocus被归还后
再恢复播放 ;这对应于抢走AudioFocus的申请者使用了AUDIOFOCUS_GAIN_TRANSIENT*/
case AUDIOFOCUS_LOSS_TRANSIENT:
saveCurrentPlayingState();
pause();
break;
/*AudioFocus被临时夺走,允许不暂停,所以降低音量 ,这对应于抢走AudioFocus的
回放实例使用了AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK*/
case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
saveCurrentPlayingState();
setVolume(getVolume()/2);
break;
/*AudioFocus被归还,这时需要恢复被夺走前的播放状态*/
case AUDIOFOCUS_GAIN:
restorePlayingState();
break;
}
}
(2)申请audiofocus最终的结果:
跟上图有些差异,最终call到Tracks.cpp