小工具知识网

当前位置: 首页 > 行业知识 > 【Android Audio Focus 音频焦点】

行业知识

【Android Audio Focus 音频焦点】

2026-11-06 17:20:09 来源:互联网转载

介绍

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。由于焦点请求始终必须指定请求的类型,因此此类型会包含在构建器的构造函数中。使用构建器的方法来设置请求的其他字段。

        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()                }            }        }    }

    官方文档链接:管理音频焦点

上一篇:织梦CMS新栏目添加全攻略,轻松上手,一键搞定!

下一篇:2023年系统集成项目管理工程师通关攻略