1. 音频焦点是什么
两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在一起。虽然这是一项出色的技术,但却会给用户带来很大的困扰(设想下QQ音乐和酷狗音乐同时在播放)。为了避免所有音乐应用同时播放,Android 引入了“音频焦点”的概念。 一次只能有一个应用获得音频焦点。当你的应用需要输出音频时,它需要请求获得音频焦点,获得焦点后,就可以播放声音了。但是获得音频焦点,并不意味着你可以一直持有到播放完成。其他应用也可以请求焦点,从而抢占你持有的音频焦点。如果发生这种情况,你的应用应暂停播放或降低音量,以便于用户听到新的音频源。音频焦点采用协作模式。建议我们的应用遵守音频焦点准则,但系统不会强制执行这些准则。如果应用想要在失去音频焦点后继续大声播放,系统无法阻止它。这是一种不好的体验,用户很可能会卸载具有这种不良行为的应用。
2. 四种不同的音频焦点类型
Android系统一共有四种不同的音频焦点类型。通过不同的音频焦点类型请求到音频焦点后。上一个持有音频焦点的应用将有不同的表现。
- AudioManager#AUDIOFOCUS_GAIN 表示应用是用户唯一在听的音频播放来源。播放时长未知,可能很长,也可能很短,这不重要。重要的是,当应用结束后,其他的音频应用不会恢复播放。 场景:使用QQ音乐播放音乐,然后再打开酷狗音乐播放音乐,QQ音乐会暂停播放,当kill掉酷狗音乐后,QQ音乐不回主动恢复播放。该类型,会清理音频焦点堆栈。
- AudioManager#AUDIOFOCUS_GAIN_TRANSIENT 短暂获取焦点播放音频。当音频播放完毕,放弃音频焦点后。栈顶的focus request将会重新获取焦点。场景:听音乐时用微信给好友发送语音信息。录音开始时 微信获取短暂焦点,音乐暂停播放,当录音完成,发送给好友后,微信主动放弃焦点,音乐应用重新获取焦点,并且播放音乐。
- AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 这个类型和AUDIOFOCUS_GAIN_TRANSIENT类似,都是获取到短暂焦点。它们的相同之处是,当放弃掉焦点后,栈顶的focus request将重新获得请求。不同之处是AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK允许先前获取到音频焦点的应用降低音量,与新获取音频焦点的应用同时播放。场景:当我们边听音乐边打开地图导航开车时。音乐应用获取AUDIOFOCUS_GAIN类型的焦点,当导航软件提示转弯时,会获取AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK类型的音频焦点,播放导航提示音频时,会将音乐播放器的声音压低。(在android12 上系统会自动实现压低音量,其它其系统不确定会不会自动压低)。
❝
MAY_DUCK有两个需要注意的地方。
1.为什么叫MAY_DUCK。叫DUCK不行吗?DUCK的意思就是把背景音频音量压低。比如,导航音频播报时将音乐播放器的音量压低。MAY有两种可能性,音乐播放器可以选择被动被系统将音量压低,也可以选择主动暂停播放。那么如何选择主动暂停播放呢?音乐播放器获取焦点时调用 setWillPauseWhenDucked(true)
2.相同的进程不能DUCK。同一个进程的不同功能模块,请求AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,不会压低音量。只有进程之间,某个进程获取到AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK类型的音频焦点之后,才会将先前获取到音频焦点的进程的音量压低❞
- AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE这也是获取短暂焦点。但是它可能会让后来的获取音频焦点的APP播放不出声音。 场景,录音时,通知音会被禁默。
❝
有一个比较特殊的音频类型AudioFocus_For_Phone_Ring_And_Calls。它表示打电话时获取的音频焦点。它的优先级最高。它可以抢占其它应用的音频焦点,而且其它应用不能抢占它的音频焦点。但是可以通过setAcceptsDelayedFocusGain(true)方法,在打完电话后获取音频焦点。 场景打电话的时候,打开游戏软件,此时游戏软件不出声,打完电话后游戏软件会播放背景音乐。❞
3. Demo 演示
App1 | App2 |
---|---|
请求长焦点 | 请求长焦点 |
请求短焦点 | 请求短焦点 |
请求Duck焦点 | 请求Duck焦点 |
请求独占焦点 | 请求独占焦点 |
一共有16种组合。具体请参考代码。 https://gitee.com/jiangbin23/mediafocus.git
4. 场景
1. 播放音乐时,打开另一个音乐软件
坏的用户体验👇
好的用户体验👇
2. 播放音乐时,来电话了
坏的用户体验👇
好的用户体验👇
3. 导航时播放音乐
如果不处理音频焦点问题,那么导航播报和音乐会同时播放,这样用户可能会听不清导航指令。正确的做法,当播放导航指令时,音乐播放器降低音量。当播报完成后,音乐播放器恢复音量。
4. 打电话时,启动带音频播放的游戏软件
如果不处理音频焦点问题,那么游戏声音和电话声音会同时播放,用户体验糟糕。正确的做法,打电话时,启动游戏,游戏请求焦点失败,游戏不播放音乐。当电话结束时,游戏获取到焦点,播放音乐。setAcceptsDelayedFocusGain(true)
5. 发送通知,闹钟,导航
对于短暂急促的通知音,可以降低背景音乐的音量。也可以将背景音乐暂停
6. 录音或者语音识别
应该获取独占类型的语音焦点。这样通知不会发出声音,不会将通知音录制进去。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/8641.html