音频焦点管理例子
启用自动管理后禁止手动调用音频焦点API,否则会破坏内部状态机。
以下是音频焦点管理的具体实现示例,涵盖不同场景和平台特性:
一、传统Android音频焦点管理(手动请求)
public class MediaPlayerService extends Service {
private AudioManager audioManager;
private MediaPlayer mediaPlayer;
private AudioFocusRequest focusRequest; // Android O+
@Override
public void onCreate() {
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
}
public void startPlayback() {
// 1. 请求音频焦点
if (requestAudioFocus() != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) return;
// 2. 初始化播放器
mediaPlayer = MediaPlayer.create(this, R.raw.sample);
mediaPlayer.start();
}
private int requestAudioFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AudioAttributes attrs = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(attrs)
.setOnAudioFocusChangeListener(focusChangeListener)
.build();
return audioManager.requestAudioFocus(focusRequest);
} else {
return audioManager.requestAudioFocus(
focusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
);
}
}
// 3. 焦点变化监听
private OnAudioFocusChangeListener focusChangeListener = focusChange -> {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_LOSS:
handleStopPlayback(); // 永久失去焦点
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
mediaPlayer.pause(); // 临时暂停
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mediaPlayer.setVolume(0.3f, 0.3f); // 降低音量
break;
case AudioManager.AUDIOFOCUS_GAIN:
mediaPlayer.setVolume(1.0f, 1.0f); // 恢复音量
if (!mediaPlayer.isPlaying()) mediaPlayer.start();
break;
}
};
// 4. 释放资源
private void releaseResources() {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioManager.abandonAudioFocusRequest(focusRequest);
} else {
audioManager.abandonAudioFocus(focusChangeListener);
}
}
}
关键处理逻辑:
- 永久失去焦点 (
AUDIOFOCUS_LOSS) → 停止播放并释放资源 - 临时失去焦点 (
AUDIOFOCUS_LOSS_TRANSIENT) → 暂停播放 - 允许闪避 (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) → 音量降至30%
二、AAOS并发焦点模式实现
// 适用于车载导航提示音播放
public void playNavigationPrompt() {
AudioAttributes attrs = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build();
// 关键配置:MAY_DUCK类型 + 禁用暂停策略
AudioFocusRequest request = new AudioFocusRequest.Builder(
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
.setAudioAttributes(attrs)
.setWillPauseWhenDucked(false) // 必须禁用暂停策略
.build();
if (audioManager.requestAudioFocus(request) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// 系统自动降低背景音乐音量至50%
navigationPlayer.start();
}
}
// 焦点监听器实现(简化)
private OnAudioFocusChangeListener listener = focusChange -> {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
// 无需操作!系统自动处理音量闪避
}
};
并发模式强制要求:
- 请求类型必须为
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK - 必须调用
setWillPauseWhenDucked(false) - 音频属性需明确声明为导航类型 (
USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
三、ExoPlayer自动管理方案
// 自动处理焦点请求/释放(推荐媒体应用使用)
exoPlayer.setAudioAttributes(
new com.google.android.exoplayer2.audio.AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build(),
true // 启用自动焦点管理
);
// 播放时自动触发:
exoPlayer.setMediaItem(MediaItem.fromUri(uri));
exoPlayer.prepare();
exoPlayer.play(); // 内部自动请求焦点
注意:启用自动管理后禁止手动调用音频焦点API,否则会破坏内部状态机。
四、多音区焦点管理(AAOS专用)
<!-- car_audio_configuration.xml 配置示例 -->
<volumeGroups>
<group>
<device address="bus0_media_out">
<context context="music"/> <!-- 媒体焦点组 -->
</device>
</group>
<group>
<device address="bus1_navigation_out">
<context context="navigation"/> <!-- 导航焦点组 -->
</device>
</group>
</volumeGroups>
实现特性:
- 独立音区独立焦点管理
- 通过音频上下文 (
context) 定义焦点组 - 支持驾驶员区域优先策略
⚠️ 关键差异总结
场景 焦点请求类型 音量控制方式 传统Android AUDIOFOCUS_GAIN 应用手动调整 AAOS并发模式 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 系统自动闪避 ExoPlayer 自动选择 播放器自主管理
引用链接:
1.音频焦点 | Android Open Source Project - Android
2.AAOS 音频焦点请求 - CSDN博客
3.【AAOS】【源码分析】CarAudioService(二)-- 功能介绍 - CSDN博客
4.音量管理 | Android Open Source Project - Android
5.HarmonyOS多音频播放并发政策及音频管理解析 - 博客园
6.android AAOS android aaos 输入 - 51CTO博客
7.关于音频焦点的理解 - CSDN
8.Android Automotive 虚拟化 - 铁阳聊汽车
9.Axios 并发请求实战 - 掌握这 3 种实现技巧 - Apifox
10.Android14音频进阶之AAOS音频焦点(七十一) - CSDN博客
11.简单易懂的方式解决 Axios 并发请求的 3 招 - 51CTO博客
12.网络编程(18)——使用asio协程实现并发服务器demo(官方案例) - 爱吃土豆
13.Automotive audio策略总结 - CSDN博客
14.架构| Android Open Source Project - Android
15.车载音频 - Android
16.Android车载开发启示录|媒体篇-音频焦点 - 稀土掘金
17.并发编程系列-Semaphore - 架构师刘欣
18.HarmonyOS开发中如何实现相机手动对焦? - 思否开发者社区
19.Android车载开发启示录|媒体篇-音频焦点 - 掘金开发者社区
20.Java并发源码AQS - 杨京京
21.鸿蒙5开发宝藏案例分享—应用并发设计 - 腾讯云
22.简体中文 - 华为开发者联盟
23.音频焦点 | Android Open Source Project - Android
24.OpenHarmony音频焦点模式开发 - CSDN博客
25.系统学习AutoSAR ETAS RTA-OS嵌入式操作系统(三)任务Tasks - 艾格北峰汽车电子
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)