安卓官方文档带你学车载音频焦点

张开发
2026/4/14 18:36:02 15 分钟阅读

分享文章

安卓官方文档带你学车载音频焦点
音频焦点在启动逻辑声音流之前应用会使用与逻辑声音流相同的音频属性来请求音频焦点。应用必须尊重焦点损失以便在汽车用例中按预期运行。虽然我们建议发送焦点请求但系统不会强制要求发送。因此请将焦点视为间接控制和避免播放期间发生冲突的手段而不是主要的音频控制机制。车辆不应依赖焦点系统来操作音频子系统。焦点交互为了支持 AAOS系统会根据请求的 CarAudioContext 和当前焦点持有者的 CarAudioContext 之间的预定义交互来处理音频焦点请求。交互分为三种类型独占拒绝并发独占交互这是 Android 中最常用的交互模型。在独占交互中一次只允许一个应用持有焦点。因此在传入的焦点请求被授予焦点的同时现有的焦点持有者会失去焦点。由于两个应用都播放媒体因此仅允许一个应用持有焦点。结果就是新启动的应用发出的焦点请求将返回 AUDIOFOCUS_REQUEST_GRANTED而当前播放音乐的应用将收到焦点更改事件该事件中的丢失状态与所发请求的类型相对应。拒绝交互在拒绝交互中传入的请求一律会遭到拒绝。例如在通话过程中尝试播放音乐。在这种情况下如果拨号器为某个通话持有音频焦点而第二个应用请求获得焦点以播放音乐则音乐应用发出的请求会收到 AUDIOFOCUS_REQUEST_FAILED 响应。由于焦点请求遭拒因此系统不会向当前焦点持有者分派任何焦点丢失事件。并发交互并发交互是 AAOS 独有的。在这种交互模式下请求音频焦点的车载应用可与其他应用同时持有焦点。若要实现并发交互必须满足以下条件。即传入的焦点请求必须请求 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK当前焦点持有者不会 setPauseWhenDucked(true)当前焦点持有者选择不接收闪避事件如果满足上述条件焦点请求将返回 AUDIOFOCUS_REQUEST_GRANTED而当前焦点持有者的焦点不会发生任何变化。不过如果当前焦点持有者选择接收闪避事件或在闪避时暂停则会失去焦点就像独占交互一样。处理并发声音流虽然并发交互有很多用途但是在硬件级别跨输出设备进行混音和降低音量时要小心。我们强烈建议将允许同时播放的 CarAudioContext 路由到不同的输出设备。通过为并发声音流提供单独的输出设备HAL 便可在混音之前对其中一个声音流进行闪避或者将物理声音流路由到车辆中的其他音响设备。如果在 Android 中对逻辑声音流进行混音则增益将保持不变并作为同一物理声音流的一部分进行传递。例如如果同时提供导航提示音和媒体播放声音媒体声音流的增益会暂时降低或闪避以便用户能更清楚地听到导航提示。或者导航声音流会被路由到驾驶员身旁的音响设备媒体则在驾驶舱的其余音响设备中继续播放。交互矩阵下表显示了由 CarAudioService 定义的交互矩阵。每行都代表当前焦点持有者的 CarAudioContext每列都代表传入请求的 CarAudioContext。例如如果导航应用请求获得焦点时音乐媒体应用持有焦点此矩阵会指示这两种交互可以并行播放假设满足并发交互的其他条件。由于并发交互的缘故可能会存在多个焦点持有者。在这种情况下系统会将传入的焦点请求与当前的各个焦点持有者进行比较然后决定应用哪种交互。此时最保守的交互会胜出。先是拒绝交互然后是独占交互最后是并发交互。图 1. 音频焦点交互矩阵。在通话期间导航Android 11 中引入了一项新的用户设置可让用户更改导航与通话之间的交互行为。设置后android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL 会将传入的焦点请求 NAVIGATION 与当前焦点持有者 CALL 之间的交互从“并发”变为“拒绝”。如果用户不希望导航指示中断通话则可以启用此设置。系统会为用户保留此设置但可以动态设置以便后续焦点请求遵循新设置。可延迟的音频焦点在 Android 11 中AAOS 开始支持请求获得可延迟的音频焦点。这样一来当非瞬态焦点请求与当前焦点持有者交互通常会遭到拒绝时前者可以延迟。一旦焦点的变化导致延迟的请求可以获得焦点系统就会将焦点授予该请求。延迟音频焦点请求的规则仅限非瞬态请求。只能针对非瞬态来源发出延迟请求以免在不相关时刻之后很长时间还播放瞬态声音。一次只能延迟一项请求。如果在已有一项延迟请求的情况下又发出另一项延迟请求则最初发送的延迟请求将收到 AUDIOFOCUS_LOSS 更改事件新发送的请求将收到 AUDIOFOCUS_REQUEST_DELAYED 的同步响应。可延迟的请求必须具有 OnAudioFocusChangeListener。请求延迟后监听器将用于在请求最终获得焦点 (AUDIOFOCUS_GAIN) 或稍后被拒绝 (AUDIOFOCUS_LOSS) 时通知请求者。请求可延迟的焦点如需构建可以延迟的请求请使用 AudioFocusRequest.Builder#setAcceptsDelayedFocusGain。mMediaWithDelayedFocusListenernewMediaWithDelayedFocusListener();mDelayedFocusRequestnewAudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).setAudioAttributes(mMusicAudioAttrib).setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener).setForceDucking(false).setWillPauseWhenDucked(false).setAcceptsDelayedFocusGain(true).build();在发出请求时处理 AUDIOFOCUS_REQUEST_DELAYED 响应intdelayedFocusRequestResultsmAudioManager.requestAudioFocus(mDelayedFocusRequest);if(delayedFocusRequestResultsAudioManager.AUDIOFOCUS_REQUEST_GRANTED){// start audio playbackreturn;}if(delayedFocusRequestResultsAudioManager.AUDIOFOCUS_REQUEST_DELAYED){// audio playback delayed to audio focus listenerreturn;}在请求获得延迟后焦点监听器负责处理焦点变更privatefinalclassMediaWithDelayedFocusListenerimplements OnAudioFocusChangeListener{OverridepublicvoidonAudioFocusChange(intfocusChange){synchronized(mLock){switch(focusChange){caseAudioManager.AUDIOFOCUS_GAIN:…// Start focus playbackcaseAudioManager.AUDIOFOCUS_LOSS_TRANSIENT:…// Pause media transientlycaseAudioManager.AUDIOFOCUS_LOSS:…// Stop media多音频区焦点管理对于具有多个音频区的车辆系统会为每个音频区单独管理音频焦点。因此对一个音频区的请求不会考虑其他音频区中的焦点持有者也不会导致其他音频区中的焦点持有者失去焦点。因此主驾驶舱与后座娱乐系统的焦点可分开管理从而避免某个音频区的焦点变更时另一个音频区的播放也随之中断。对于所有应用CarAudioService 都会自动管理焦点。焦点请求的音频区由其关联的 UserId 或 UID 确定如需了解详情请参阅多区音频路由。同时从多个音频区请求音频如果应用需要同时在多个音频区播放音频就必须在软件包中包含 AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID以针对各个音频区请求焦点//Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_IDBundle bundlenewBundle();bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,zoneId);AudioAttributes attributesWithZonenewAudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).addBundle(bundle).build();//Create focus request using built attributesWithZone此软件包参数允许请求者替换自动音频区映射以改用指定的音频区 ID。因此应用可针对不同的音频区发出单独的请求。HAL 音频焦点从 Android 11 开始HAL 可以代表外部声音流请求焦点。虽然这些 API 是可选的但我们强烈建议您使用以便启用外部声音从而成为 Android 生态系统的最佳参与者并提供无缝的用户体验。关于应优先使用哪些声音最终由 HAL 决定。因此无论 HAL 是否被授予音频焦点都应播放紧急声音或对保障安全至关重要的声音即使 HAL 失去音频焦点也应继续在适当的情况下播放这些声音。此规则也适用于政府法规要求的任何声音。为了确保人们能够清楚地听到HAL 应在播放紧急声音或对保障安全至关重要的声音时适时主动将 Android 声音流静音。2.0 版 AudioControl2.0 版 AudioControl HAL 引入了以下新 APIAPI 用途HAL 可以同时拥有多个焦点请求但每个用法与音频区 ID 的配对仅限一个请求。Android 会假定HAL 将在请求发出后针对某个使用行为立即开始播放声音并在放弃焦点之前继续执行同样的操作。除 registerFocusListener 之外这些请求为 oneway以确保 Android 在处理焦点请求时不会延迟 HAL。在播放对保障安全至关重要的声音前HAL 不应等待获得焦点。HAL 通过 IAudioControl#onAudioFocusChange 监听和响应音频焦点的变化是可选操作。OEM 车载音频焦点服务在 Android 14 中AAOS 引入了汽车 OEM 插件服务以便某些汽车组件具有可配置性。对于车载音频插件服务OEM 可以通过该插件服务管理由车载音频服务拦截的焦点请求。这样一来OEM 可以根据规则和法规的要求更灵活地管理焦点。因此音频焦点交互可能因制造商和地区而异。音频焦点的基本前提仍然适用即应用仍应请求焦点以更好地管理音频从而增强用户体验。一般来说某些规则仍适用于应用的音频焦点请求在没有任何高优先级音频焦点包括通话、紧急警报或安全通知的情况下应用应能暂时或永久获得音频焦点。当媒体焦点处于活跃状态时请求通话使用焦点的应用应能够同时或独占地接收通话。请求导航使用焦点的应用应能够同时或独占地接收导航焦点。请求 Google 助理使用焦点的应用应能够同时或独占地接收使用焦点。当高优先级音频焦点包括通话、紧急警报或安全通知的应用处于活跃状态时应根据需要批准或延迟传入的延迟音频焦点请求。虽然上述建议并非详尽无遗但有助于请求焦点的应用在没有处于活跃状态的高优先级声音时能够获得焦点。即使高优先级声音处于活跃状态也应遵从延迟的焦点请求并应能在高优先级声音停止后获得焦点。audio课程其他课程活动具体感兴趣的朋友了解详细请关注下面“千里马学框架”

更多文章