转自:http://mobile.51cto.com/android-309321.htm

因为系统中可能会有多个应用程序会播放音频,所以需要考虑他们之间该如何交互,为了避免多个应用程序同时播放音乐,Android 系统使用音频焦点来进行统一管理,即只有获得了音频焦点的应用程序才可以播放音乐。

您的应用程序在开始播放音频文件前,首先应该请求获得音频焦点,并且应该同时注册监听音频焦点的丢失通知,即如果音频焦点被系统或其他的应用程序抢占时,您的应用程序可以做出合适的响应。

获取音频焦点

您的应用程序在开始播放任何音频之前,首先应该持有流的音频焦点。

可以通过调用 requestAudioFocus()  来实现,如果请求成功,返回 AUDIOFOCUS_REQUEST_GRANTED 。

您必须指定流类型(使用的是哪一个流)和音频焦点的类型(短暂的或是持久的)。

瞬态焦点用来播放很短时间的音频(例如,播放导航指令)。

持久焦点用来播放较长一段时间的音频(例如,播放音乐)。

下面的代码片断演示了请求音乐音频流的永久音频焦点。

例如当用户按下播放背景音乐的按键,您应该立即请求音频焦点,当成功获得了焦点后再开始播放音乐。

  1. AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
  2. ...
  3. // Request audio focus for playback
  4. int result = am.requestAudioFocus(afChangeListener,
  5. // Use the music stream.
  6. AudioManager.STREAM_MUSIC,
  7. // Request permanent focus.
  8. AudioManager.AUDIOFOCUS_GAIN);
  9. if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
  10. am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
  11. // Start playback.
  12. // 开始播放音乐文件
  13. }

一旦您的应用程序完成了播放,请记得要调用 abandonAudioFocus()  方法来通知系统释放音频焦点,同时注销相关的 AudioManager.OnAudioFocusChangeListener 。这样当您的应用程序释放了音频焦点,则系统会允许其他被中断的应用程序重新获取该焦点来继续播放。

  1. // Abandon audio focus when playback complete
  2. am.abandonAudioFocus(afChangeListener);

当请求瞬态音频焦点时有一个附加参数可供设置,即是否允许 “DUCK”。通常当应用程序失去了音频焦点时应该停止播放。如果获取短暂音频焦点的时候设置了”DUCK” 附加参数,则允许其他的应用程序继续播放,不需要停止,只要降低音量就可以了,然后直到您的应用程序释放了焦点,其他应用程序再重新获得的时候,将音量还 原到有一开始的状态。

  1. // Request audio focus for playback
  2. int result = am.requestAudioFocus(afChangeListener,
  3. // Use the music stream.
  4. AudioManager.STREAM_MUSIC,
  5. // Request permanent focus.
  6. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
  7. if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
  8. // Start playback.
  9. }

“DUCK” 特别适合那种间歇性播放音频流的应用程序,如驾驶导航的声音提示。

每当其他的应用程序请求获得音频焦点(永久性的,短暂的,短暂并且支持DUCK的)的时候,您应用程序中注册的音频焦点监听器都会收到相应的消息通知。

处理音频焦点的丢失

如果您的应用程序可以请求音频焦点,那么当其他应用程序申请的时候,您的应用程序也可能会丢失音频焦点。怎么样应对音频焦点丢失的情况则取决于音频焦点丢失的方式。

当音频焦点丢失时,您注册的监听函数onAudioFocusChange()会收到一个事件通知,通知中的参数包括了具体的信息,比如是永久焦点丢失,短暂焦点丢失,还是短暂焦点且允许DUCK的焦点丢失。

通常,如果是短暂焦点的丢失,您的应用程序应该暂停当前的播放,但其他状态信息继续保持,并且应该持续监听音频焦点的改变,一旦重新获得了音频焦点,则可以马上恢复到以前的播放状态。

假如是永久焦点的丢失,则通常意味着其他应用程序要长时间播放音频了,您的应用程序应该停止播放,放弃音频焦点的监听,并注销所有的媒体按钮监听 器,从而让获得焦点的其他应用程序来监听媒体播放控制按钮的按键消息。如果要恢复您应用程序的播放状态,则通常需要用户重新启动您的应用程序。

在下面的代码片段中,如果丢失的是短暂音频焦点,则暂定当前应用程序的播放,如果丢失的是永久音频焦点,则停止当前应用程序的播放,停止监听音频焦点的变更,并注销媒体按钮事件的监听。

  1. OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
  2. public void onAudioFocusChange(int focusChange) {
  3. if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT
  4. // Pause playback
  5. } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
  6. // Resume playback
  7. } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
  8. am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
  9. am.abandonAudioFocus(afChangeListener);
  10. // Stop playback
  11. }
  12. }
  13. };

如果丢失的短暂音频焦点允许DUCK状态,在这种情况下,应用程序降低音量继续播放,不需要暂停。

Duck!

DUCK:降低您应用程序的音量,从而不会打扰其他应用程序音频的播放。

在下面的代码片段中,当我们失去焦点的时候,降低了媒体播放的音量,重新获得焦点的时候,将音量恢复到原来的状态。

  1. OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
  2. public void onAudioFocusChange(int focusChange) {
  3. if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
  4. // Lower the volume
  5. } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
  6. // Raise it back to normal
  7. }
  8. }
  9. };

音频焦点的丢失是非常重要的一种系统状态变化通知,系统会广播很多有关音频状态变化的通知,您的应用程序应该监听这些变化,并作出合适的应对方案,从而提高用户的音乐体验。

参考文摘:

http://developer.android.com/training/managing-audio/audio-focus.html

原文链接:

http://blog.zhourunsheng.com/2011/12/android-%E9%9F%B3%E4%B9%90%E7%BC%96%E7%A8%8B%E4%B8%93%E9%A2%98%E4%B9%8B%E7%AE%A1%E7%90%86%E9%9F%B3%E9%A2%91%E7%84%A6%E7%82%B9/

Android音乐编程:管理音频焦点相关推荐

  1. android汽车音频焦点方案,管理音频焦点  |  Android 开发者  |  Android Developers

    两个或两个以上的 Android 应用可同时向同一输出流播放音频.系统会将所有音频流混合在一起.虽然这是一项出色的技术,但却会给用户带来很大的困扰.为了避免所有音乐应用同时播放,Android 引入了 ...

  2. Android官方开发文档Training系列课程中文版:管理音频播放之管理音频焦点

    原文地址:http://android.xsoftlab.net/training/managing-audio/audio-focus.html 因为可能会存在多个APP播放音频,所以考虑它们之间的 ...

  3. 创建多媒体APP 之 音频播放:管理音频焦点

    因为很多APP都会潜在需要去播放音频文件,所有要考虑多个APP在播放音频文件的时候会产生的影响,这个非常重要.为了防止同时有多个APP播放音频,android采用了音频焦点这个概念来节制APP对音频的 ...

  4. Android 9.0失去音频焦点后不能再获取到焦点

    问题 在9.0版本上,A先申请音频焦点,B先申请再释放音频焦点后,A也不能收到onAudioFocusChange回调,导致不能继续播放. 但是在7.1版本,这种情况是会正常播放的. 分析过程 查看源 ...

  5. Android音频焦点申请处理

    为了便于理解,我们以android的8.0以前的版本为例,8.0以后有一定改动,但是基本思路一样. 关于管理音频焦点(8.0以前和更高版本)的官方文档:https://developer.androi ...

  6. android音频焦点Audio Focus

    为了便于理解,我们以android的8.0以前的版本为例,8.0以后有一定改动,但是基本思路一样. 关于管理音频焦点(8.0以前和更高版本)的官方文档:https://developer.androi ...

  7. Android音频焦点及混音策略

    1.前言 1.1 音频焦点官方解读 两个或两个以上的 Android 应用可同时向同一输出流播放音频.系统会将所有音频流混合在一起.虽然这是一项出色的技术,但却会给用户带来很大的困扰.为了避免所有音乐 ...

  8. Android 音频焦点处理

    刚开始的时候,认为在智能机中,每个 APP 都是各自管各自的,媒体播放也是这样子的:然而对比同类产品,发现同类产品可以放到播放自如,体验很好,通过对比研究,根源就在于音频焦点处理上. 一.引言 在功能 ...

  9. Android音频焦点处理

    概要 Android系统允许多个应用同时播放音频,这种特性有利有弊.例如当我们正在听音乐的时候突然点开了一个视频,如果我们发现音乐的声音和视频的的声音混合了在一起,这显然让我们非常不爽.而如果我们在播 ...

最新文章

  1. 第四篇[机器学习] 机器学习,线性回归的优化
  2. 毛坦厂中学是“高考工厂”?白岩松:我做不出嘲讽它的事情!
  3. 如何查看python解释器位置_Python:查看解释器的位置
  4. 基于bitbucket中央库的Git操作
  5. 易语言下载别人的源码编译出来用不了_我是如何阅读源码的
  6. 韩国有多大?相当于中国哪里?
  7. 01.学习笔记-linux操作系统常用命令
  8. 一个java错误的总结
  9. 根据银行卡号获取银行名称、编码、类型
  10. 前端谷歌浏览器显示海康rtsp视频
  11. 公开说说别人看不到_为什么我在QQ空间里面发表说说别人看不到
  12. oracle数据库查看scanip,rac下查看scanip 在哪個節點上
  13. C++ stack 遍历
  14. 数据库上机实验八(视图)
  15. JS打印99乘法表格
  16. 跨境电商难做?你需要知道这5个“低成本低风险”跨境电商项目
  17. IT开发的岔路口:究竟是Java好还是嵌入式好?
  18. unity 实验演示 教程_铁匠常见问题解答和Unity演示团队
  19. asp毕业设计——基于asp+access的校园网物品交易平台设计与实现(毕业论文+程序源码)——校园网物品交易平台
  20. Queuing HDU2604

热门文章

  1. 南京是六朝文学的中心
  2. QML实现仿酷狗音乐播放器(支持在线和本地播放)
  3. 聚焦WAVE SUMMIT 2021,大咖齐聚共研深度学习
  4. evus是什么意思_不知道EVUS是什么鬼?有美签你也去不了美国!
  5. 王者荣耀s20服务器维护,王者荣耀S20开启时间
  6. StarSharks 也无法逃离 GameFi 的死亡螺旋吗?
  7. 打印机清洁墨盒的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  8. Element-ui的使用
  9. sql语句修改某个字段的部分内容
  10. 游戏策划学习:乱敏、mmo、跳跃表现