Android音频焦点
Android 音频 焦点
2023-09-14 09:10:00 时间
因为系统中可能会有多个应用程序会播放音频,所以需要考虑他们之间该如何交互,为了避免多个应用程序同时播放
音乐,Android 系统使用音频焦点来进行统一管理,即只有获得了音频焦点的应用程序才可以播放音乐。
您的应用程序在开始播放音频文件前,首先应该请求获得音频焦点,并且应该同时注册监听音频焦点的丢失通知,即
如果音频焦点被系统或其他的应用程序抢占时,您的应用程序可以做出合适的响应。
获取音频焦点
您的应用程序在开始播放任何音频之前,首先应该持有流的音频焦点。
可以通过调用 requestAudioFocus() 来实现,如果请求成功,返回 AUDIOFOCUS_REQUEST_GRANTED 。
您必须指定流类型(使用的是哪一个流)和音频焦点的类型(短暂的或是持久的)。
瞬态焦点用来播放很短时间的音频(例如,播放导航指令)。
持久焦点用来播放较长一段时间的音频(例如,播放音乐)。
下面的代码片断演示了请求音乐音频流的永久音频焦点。
例如当用户按下播放背景音乐的按键,您应该立即请求音频焦点,当成功获得了焦点后再开始播放音乐。
- AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
- ...
- // Request audio focus for playback
- int result = am.requestAudioFocus(afChangeListener,
- // Use the music stream.
- AudioManager.STREAM_MUSIC,
- // Request permanent focus.
- AudioManager.AUDIOFOCUS_GAIN);
- if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
- // Start playback.
- // 开始播放音乐文件
- }
一旦您的应用程序完成了播放,请记得要调用 abandonAudioFocus() 方法来通知系统释放音频焦点,同时注销相关
的 AudioManager.OnAudioFocusChangeListener 。这样当您的应用程序释放了音频焦点,则系统会允许其他被中断
的应用程序重新获取该焦点来继续播放。
- // Abandon audio focus when playback complete
- am.abandonAudioFocus(afChangeListener);
当请求瞬态音频焦点时有一个附加参数可供设置,即是否允许 “DUCK”。通常当应用程序失去了音频焦点时应该停止播放。如果获取短暂音频焦点的时候设置了”DUCK” 附加参数,则允许其他的应用程序继续播放,不需要停止,只要降低音量就可以了,然后直到您的应用程序释放了焦点,其他应用程序再重新获得的时候,将音量还原到有一开始的状态。
- // Request audio focus for playback
- int result = am.requestAudioFocus(afChangeListener,
- // Use the music stream.
- AudioManager.STREAM_MUSIC,
- // Request permanent focus.
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
- if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
- // Start playback.
- }
“DUCK” 特别适合那种间歇性播放音频流的应用程序,如驾驶导航的声音提示。
每当其他的应用程序请求获得音频焦点(永久性的,短暂的,短暂并且支持DUCK的)的时候,您应用程序中注册的音频焦点监听器都会收到相应的消息通知。
处理音频焦点的丢失
如果您的应用程序可以请求音频焦点,那么当其他应用程序申请的时候,您的应用程序也可能会丢失音频焦点。怎么样应对音频焦点丢失的情况则取决于音频焦点丢失的方式。
当音频焦点丢失时,您注册的监听函数onAudioFocusChange()会收到一个事件通知,通知中的参数包括了具体的信息,比如是永久焦点丢失,短暂焦点丢失,还是短暂焦点且允许DUCK的焦点丢失。
通常,如果是短暂焦点的丢失,您的应用程序应该暂停当前的播放,但其他状态信息继续保持,并且应该持续监听音频焦点的改变,一旦重新获得了音频焦点,则可以马上恢复到以前的播放状态。
假如是永久焦点的丢失,则通常意味着其他应用程序要长时间播放音频了,您的应用程序应该停止播放,放弃音频焦点的监听,并注销所有的媒体按钮监听 器,从而让获得焦点的其他应用程序来监听媒体播放控制按钮的按键消息。如果要恢复您应用程序的播放状态,则通常需要用户重新启动您的应用程序。
在下面的代码片段中,如果丢失的是短暂音频焦点,则暂定当前应用程序的播放,如果丢失的是永久音频焦点,则停止当前应用程序的播放,停止监听音频焦点的变更,并注销媒体按钮事件的监听。
- OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
- public void onAudioFocusChange(int focusChange) {
- if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT
- // Pause playback
- } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
- // Resume playback
- } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
- am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
- am.abandonAudioFocus(afChangeListener);
- // Stop playback
- }
- }
- };
- 如果丢失的短暂音频焦点允许DUCK状态,在这种情况下,应用程序降低音量继续播放,不需要暂停。
- Duck!
- DUCK:降低您应用程序的音量,从而不会打扰其他应用程序音频的播放。
- 在下面的代码片段中,当我们失去焦点的时候,降低了媒体播放的音量,重新获得焦点的时候,将音量恢复到原来的状态。
- OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
- public void onAudioFocusChange(int focusChange) {
- if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
- // Lower the volume
- } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
- // Raise it back to normal
- }
- }
- };
音频焦点的丢失是非常重要的一种系统状态变化通知,系统会广播很多有关音频状态变化的通知,您的应用程序应该监听这些变化,并作出合适的应对方案,从而提高用户的音乐体验。
参考文摘:
http://developer.android.com/training/managing-audio/audio-focus.html
相关文章
- android+制作开机动画,Android 开机动画制作详解
- android系统开机画面_Android开机画面
- 代码加密 android,Android 开发怎样做代码加密或混淆「建议收藏」
- android 空间分享到朋友圈,Android开发之微信分享到好友,朋友圈
- strictmode android,Android中的StrictMode
- strictmode android,(十三)Android 性能优化 StrictMode
- android_混淆
- mac 电脑android环境变量设置,mac上Android环境变量配置[通俗易懂]
- android sdk manager安装,Android SDK Manager安装过程
- android 获取收到短信验证码,Android自动获取短信验证码
- android短信验证码代码,Android短信验证码自动填写实现代码
- 基于Android开发的天气预报app(源码下载)「建议收藏」
- android跳转到相册需要权限,Android打开相册获取图片路径[通俗易懂]
- Android resource linking failed
- 【Android 应用开发】UI绘制流程 ( 生命周期机制 | 布局加载机制 | UI 绘制流程 | 布局测量 | 布局摆放 | 组件绘制 | 瀑布流布局案例 )
- 【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 )
- 【Android 高性能音频】Oboe 播放器开发 ( 为 OpenSL ES 配置参数以获得最佳延迟 | Oboe 音频流 | Oboe 音频设备 )
- 谷歌:Android 内存安全漏洞比例下降与使用 Rust 相关
- 【Android 逆向】Android 逆向方法 ( 静态逆向解析 | 函数调用分析 | 动态运行跟踪 | 运行日志分析 | 文件格式解析 | 敏感信息分析 | 网络信息监控 | 环境伪装模拟 )
- 【Android 逆向】Android 中常用的 so 动态库 ( 拷贝 /system/lib/ 中的 Android 系统 so 动态库 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑫ ( Gradle 任务的输出和输出 | @Optional 注解 | UP-TO-DATE 避免重复执行任务 )
- 【Android Gradle 插件】组件化中的 Gradle 构建脚本实现 ⑤ ( 优化 Gradle 构建脚本 | 构建脚本结构 | 闭包定义及用法 | 依赖配置 | android 块配置 )
- 使用Android实现连接MySQL数据库:实现快速数据交互与管理(android连接mysql数据库)
- 乐动力推手表管家:Android Wear的中国化之路
- android版本检测Android程序的版本检测与更新实现介绍
- 安装android开发环境原始版(windows版)
- Android笔记之:onConfigurationChanged详解
- android如何设置开机后屏幕亮度默认值为自动调节