Android Car&Source 04 -- Android 10 AudioFocus

    仅为学习记录,感谢所有技术分享

Android10.0AudioFocus之如何使用(一)

Android AudioFocus音频焦点机制学习和理解

Android10.0AudioFocus之AudioFocusRequest

音频焦点AudioFocus

目录

1.AudioManager中焦点durationHint定义说明

2.MediaFocusControl.java中的requestAudioFocus方法过程

 3.FocusRequester处理FocusRequester对象

4.AudioFocus流程


 

音频焦点是规则,是个弱管理。也就是说如果你想播放,不管拿不拿得到音频焦点,都是可以播放的。影响的只是体验效果,不是播放问题

1.AudioManager中焦点durationHint定义说明

  1. AUDIOFOCUS_GAIN:长时间获取焦点,一般用于音视频。此参数会触发其他监听器的AudioManager.AUDIOFOCUS_LOSS (长时间丢失焦点,这个时候需要停止播放,并释放资源。根据不同的逻辑,有时候还会释放焦点)
  2. AUDIOFOCUS_GAIN_TRANSIENT:短暂获得,一般用于电话,语音助理等。此参数会触发其他监听器的AudioManager.AUDIOFOCUS_LOSS_TRANSIENT (短暂失去焦点,这时可以暂停播放,但是不必要释放资源,因为很快又会获取到焦点)
  3. AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:短暂性获得焦点并降音,可混音播放,一般用于导航。此参数会触发其他监听器的AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK (短暂失去焦点,但是可以跟新的焦点拥有者同时播放,并做降噪处理)
  4. AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:(android后加的)与AUDIOFOCUS_GAIN_TRANSIENT类似,表示一个短暂的获取焦点,一般用于录音或者语音识别。此参数会触发其他监听器的AudioManager.AUDIOFOCUS_LOSS_TRANSIENT 

2.MediaFocusControl.java中的requestAudioFocus方法过程

    1. 判断mFocusStack值的size不能超过100
    2. 检查当前栈顶的元素是否是应用占用状态,若处于占用状态,那么focusGrantDelayed = true
    3. 压栈之前,需要检查当前栈中是否已经有这个应用的记录,如含有则删除。
      若mFocusStrack不为null(!mFocusStack.empty()),且栈顶的clientId与需要申请焦点的clientId相同(mFocusStack.peek().hasSameClient(clientId)),得到栈顶元素即FocusRequester对象。若申请的时长(focusChangeHint)及flag相同,则表示申请重复,直接返回AUDIOFOCUS_REQUEST_GRANTED;若二者有一个不同则表示需要重新申请,同时此时focusGrantDelayed为false需要将栈顶元素出栈并将其释放
    4. removeFocusStackEntry-- 移除可能在栈中(栈顶或栈中)其他位置存在着相同的clientId的元素
      • 栈顶:释放后通知栈顶应用,使其获得audioFocus
      • 非栈顶:只是移除该记录,无需更改当前audioFocus的占有情况
    5. 创建FocusRequester实例将其请求包含的各种信息传入
    6. 如果focusGrantDelayed = true会延迟申请,进入pushBelowLockedFocusOwners方法,在方法中把此次请求FocusRequester实例入栈,而非被压在栈顶,放在lastLockedFocusOwnerIndex位置,即电话记录之后,则电话的焦点释放后则该请求开始申请; 如果focusGrantDelayed = false则无需延迟获取焦点,同样创建FocusRequester实例,但需先通知栈中其他记录失去焦点,然后入栈,最后通知自己获得焦点
    7. 继续会进入propagateFocusLossFromGain_syncAf方法,遍历mFocusStack,调用FocusRequester对象的handleExternalFocusGain方法,通知栈中其他元素丢失焦点流程。通过while(stackIterator.hasNext())得到FocusRequester对象,进入handleExternalFocusGain方法
    8. notifyExtPolicyFocusGrant_syncAf做相应的通知

 3.FocusRequester处理FocusRequester对象

根据MediaFocusControl.java中propagateFocusLossFromGain_syncAf传递来的nfr.getGainRequest()值做焦点的获取/丢失处理

变量:

  1. gainRequest: 根据传入值做对应的返回值
  • 若传进来的参数是 AudioManager.AUDIOFOCUS_GAIN,return AudioManager.AUDIOFOCUS_LOSS
  • 若传进来的参数是 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
  1. mFocusLossReceived: 方法handleFocusLoss中赋值,默认为AudioManager.AUDIOFOCUS_NONE

4.AudioFocus流程

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值