介绍
Android 中的音频焦点(Audio Focus)是一种机制,用于管理应用程序之间的音频资源竞争。当多个应用程序同时请求使用音频设备时,通过音频焦点机制可以确保最终用户的体验不受影响。
两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在一起。虽然这是一项出色的技术,但却会给用户带来很大的困扰。为了避免所有音乐应用同时播放,Android 引入了“音频焦点”的概念。 一次只能有一个应用获得音频焦点。
当您的应用需要输出音频时,它需要请求获得音频焦点,获得焦点后,就可以播放声音了。不过,在您获得音频焦点后,您可能无法将其一直持有到播放完成。其他应用可以请求焦点,从而占有您持有的音频焦点。如果发生这种情况,您的应用应暂停播放或降低音量,以便于用户听到新的音频源。
音频焦点采用合作模式。我们建议应用遵守音频焦点准则,但系统不会强制执行这些准则。如果应用想要在失去音频焦点后继续大声播放,系统无法阻止它。这是一种不好的体验,用户很可能会卸载具有这种不良行为的应用。
焦点事件
-
AUDIOFOCUS_GAIN:
说明: 应用获得了音频焦点,可以继续播放音频。
处理方式: 在这个状态下,应用可以正常播放音频。在失去焦点后再次获取焦点时,通常需要在这个状态下恢复播放。 -
AUDIOFOCUS_LOSS:
说明: 【永久性失去焦点】应用失去了音频焦点,需要停止音频播放。
处理方式: 当收到 AUDIOFOCUS_LOSS 时,应用应该停止播放音频,并释放相关资源。这种情况通常是由于其他应用请求了长时间的音频焦点,例如开始播放长时间的音频文件。不要立即尝试重新获取焦点。 -
AUDIOFOCUS_LOSS_TRANSIENT:
说明: 【暂时性失去焦点】应用短暂失去了音频焦点,但可以在稍后重新获取焦点。
处理方式: 当收到 AUDIOFOCUS_LOSS_TRANSIENT 时,应用应该暂停音频播放。这种情况通常是由于短暂的通知声、铃声等情况导致的。应用通常会在稍后重新获取焦点并恢复播放。 -
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
说明: 【暂时性失去焦点】应用短暂失去了音频焦点,但可以降低音量继续播放。稍后可以重新获取焦点。
处理方式: 当收到 AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 时,应用可以选择降低音量而不是完全停止音频播放。这种情况通常用于在接收短暂通知时,应用可以继续以较低的音量播放。
暂时性失去焦点:
在暂时性失去音频焦点时,您应该继续监控音频焦点的变化,并准备好在重新获得焦点后恢复正常播放。当抢占焦点的应用放弃焦点时,您会收到一个回调 (AUDIOFOCUS_GAIN)。此时,您可以在此回调中,将音量恢复到正常水平或重新开始播放。
永久性失去焦点:
如果是永久性失去音频焦点 (AUDIOFOCUS_LOSS),则其他应用会播放音频。您的应用应立即暂停播放,因为它不会收到 AUDIOFOCUS_GAIN 回调。要想重新开始播放,用户必须执行明确的操作,例如在通知或应用界面中按播放传输控件。
代码示例
Android 8.0 及更高版本中的音频焦点:
从 Android 8.0(API 级别 26)开始,当您调用 requestAudioFocus() 时,必须提供 AudioFocusRequest 参数。要释放音频焦点,请调用 abandonAudioFocusRequest() 方法,该方法也接受 AudioFocusRequest 作为参数。在请求和放弃焦点时,应使用相同的 AudioFocusRequest 实例。
要创建 AudioFocusRequest,请使用 AudioFocusRequest.Builder。由于焦点请求始终必须指定请求的类型,因此此类型会包含在构建器的构造函数中。使用构建器的方法来设置请求的其他字段。文章来源:https://www.toymoban.com/news/detail-772377.html
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setAudioAttributes(AudioAttributes.Builder().run {
setUsage(AudioAttributes.USAGE_MEDIA)//or AudioAttributes.USAGE_GAME
setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
build()
})
setAcceptsDelayedFocusGain(true)
setOnAudioFocusChangeListener(afChangeListener, handler)
build()
}
val focusLock = Any()
var playbackDelayed = false
var playbackNowAuthorized = false
// ...
val res = audioManager.requestAudioFocus(focusRequest)
synchronized(focusLock) {
playbackNowAuthorized = when (res) {
AudioManager.AUDIOFOCUS_REQUEST_FAILED -> false
AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> {
playbackNow()
true
}
AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> {
playbackDelayed = true
false
}
else -> false
}
}
val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_LOSS -> {
// Permanent loss of audio focus. Pause playback immediately
synchronized(focusLock) {
resumeOnFocusGain = false
playbackDelayed = false
}
pausePlayback()
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
// Pause playback
synchronized(focusLock) {
resumeOnFocusGain = true
playbackDelayed = false
}
pausePlayback()
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
// ... pausing or Lower the volume depends on your app
}
AudioManager.AUDIOFOCUS_GAIN -> {
// Your app has been granted audio focus again
// Raise volume to normal, restart playback if necessary
if (playbackDelayed || resumeOnFocusGain) {
synchronized(focusLock) {
playbackDelayed = false
resumeOnFocusGain = false
}
playbackNow()
}
}
}
}
官方文档链接:管理音频焦点文章来源地址https://www.toymoban.com/news/detail-772377.html
到了这里,关于【Android Audio Focus 音频焦点】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!