Android Audio Focus的应用(requestAudioFocus)
网址:http://blog.csdn.net/dadoneo/article/details/8252933
FROM: http://www.linuxidc.com/Linux/2012-04/57902.htm
================================================
Android是多任务系统,Audio系统是竞争资源。Android2.2之前,没有内建的机制来解决多个程序竞争Audio的问题,2.2引入了称作AudioFocus的机制来管理对Audio资源的竞争的管理与协调。本文主要讲解AudioFocus的使用。
按照AudioFocus的机制,在使用AudioStream之前,需要申请AudioFocus,在获得AudioFocus之后才可以使用相应的AudioStream;如果有别的程序竞争你正在使用的AudioStream,你的程序需要在收到通知之后做停止播放或者降低声音的处理。值得指出的是,这种机制是需要合作完成的,需要所有使用Audio资源的程序都按照这种机制来做,而如果有程序在它失去AudioFocus的时候仍然在使用Audio,AudioFocus拿它也没办法。而这一点对于开放系统的Android来说很致命的:用户可能安装没遵守这种机制的程序,或者版本太老还没引入这种机制的程序,这最终会导致很差的用户体验。
对于手机方案公司来说,要做的能做的事情就是教育和培训团队成员以保证自己内建的程序遵守机制没问题,这包括了Android原生的程序、自己开发的程序,以及适配第三方的程序。
一、AudioFocus的申请与释放
下面看与AudioFocus的相关的类:
获取/放弃AudioFocus的方法都在android.media.AudioManager中,获取AudioFocus用requestAudioFocus()
;用完之后,放弃AudioFocus,用abandonAudioFocus()
。
其中,参数:
- streamType是《Android中的Audio播放:音量和远程播放控制》中说明的AudioStream,其值取决于AudioManager中的STREAM_xxx;
- durationHint是持续性的指示:
AUDIOFOCUS_GAIN
指示申请得到的Audio Focus不知道会持续多久,一般是长期占有;AUDIOFOCUS_GAIN_TRANSIENT
指示要申请的AudioFocus是暂时性的,会很快用完释放的;- AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK不但说要申请的AudioFocus是暂时性的,还指示当前正在使用AudioFocus的可以继续播放,只是要“duck”一下(降低音量)。
- AudioManager.OnAudioFocusChangeListener是申请成功之后监听AudioFocus使用情况的Listener,后续如果有别的程序要竞争AudioFocus,都是通过这个Listener的onAudioFocusChange()方法来通知这个Audio Focus的使用者的。
返回值,可能是:
- AUDIOFOCUS_REQUEST_GRANTED:申请成功;
- AUDIOFOCUS_REQUEST_FAILED:申请失败。
二、AudioFocus被抢占与重新获得
由上节中知道,申请/释放AudioFocus时传入了AudioManager.OnAudioFocusChangeListener这个参数,其onAudioFocusChange()方法是Audio Focus被抢占与再次获得通知的地方。所以,每个要使用AudioFocus的程序都要小心实现这个函数,保证AudioFocus实现的一致性。
onAudioFocusChange()方法的focusChange参数指示了该AudioFocus的竞争者对AudioFocus的拥有情况,取值如下:
- AUDIOFOCUS_GAIN:获得了Audio Focus;
- AUDIOFOCUS_LOSS:失去了Audio Focus,并将会持续很长的时间。这里因为可能会停掉很长时间,所以不仅仅要停止Audio的播放,最好直接释放掉Media资源。而因为停止播放Audio的时间会很长,如果程序因为这个原因而失去AudioFocus,最好不要让它再次自动获得AudioFocus而继续播放,不然突然冒出来的声音会让用户感觉莫名其妙,感受很不好。这里直接放弃AudioFocus,当然也不用再侦听远程播放控制【如下面代码的处理】。要再次播放,除非用户再在界面上点击开始播放,才重新初始化Media,进行播放。
- AUDIOFOCUS_LOSS_TRANSIENT:暂时失去Audio Focus,并会很快再次获得。必须停止Audio的播放,但是因为可能会很快再次获得AudioFocus,这里可以不释放Media资源;
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
:暂时失去AudioFocus,但是可以继续播放,不过要在降低音量。
下面是onAudioFocusChange()方法处理的代码片段:
- OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
- public void onAudioFocusChange(int focusChange) {
- if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
- // Pause playback
- } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
- am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
- am.abandonAudioFocus(afChangeListener);
- // Stop playback
- } else if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
- // Lower the volume
- } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
- // Resume playback or Raise it back to normal
- }
- }
- };
三、典型的应用AudioFocus的场景
下面的时序图描述了AudioFocus被抢占与再次获取的典型场景:
Audio Focus被抢占与再次获取的时序图
注意:为了描述简单,此图中除了两个竞争Audio Focus的App之外,只用AudioManager表征了Android的AudioFocus机制中内部参与的对象,实际AudioManager只是外部的表象,内部参与的对象很多,回调函数也并非简单的直接由AudioManager调用,其中还包含了复杂的IPC机制。
图中:
- AudioFocus Client通过requestAudioFocus()获取AudioFocus,在获得AudioFocus之后,开始播放Audio[Step#1 ~ #2];
- 其它程序(Other App)也通过requestAudioFocus()获取同类AudioStream的AudioFocus [Step#3]
- AudioFocus Client失去了Audio Focus,在onAudioFocusChanged()中,根据focusChange的值,做第二节中的处理[Step#4];
- 其它程序(Other App)获取Audio Focus之后,开始播放Audio[Step#5];
- 其它程序(Other App)使用Audio之后,通过
abandonAudioFocus()
归还AudioFocus [Step#6]; - AudioFocus Client重新获得了Audio Focus,可做进一步的处理 [Step#7]
小结
Audio Focus机制要参与各方充分理解并统一遵照施行,有没有遵照者或者实现有误的程序存在就可能打破这一机制,带来糟糕的用户体验。在保证Built-in程序没问题的前提下,如果进入AndroidMarket之前的程序都严格执行了AudioFocus相关的测试,应该也没问题。
相关阅读:Android中的Audio播放:控制Audio输出通道切换 http://www.linuxidc.com/Linux/2012-04/57901.htm
问题点以及进一步的探讨
- 内部裁决机制怎样的?
- 申请的不同Audio Stream之间是不存在竞争的吗?
Android Audio Focus的应用(requestAudioFocus)相关推荐
- Android 音频焦点(Audio Focus)
原址 CONTENTS 引子 音频焦点 一个简单的示例 注意: 引子 说 Audio Focus 前先说个很简单需求:来电时暂停正在播放的音乐,电话结束时恢复播放. 看到这个需求,第一反应肯定是:监听 ...
- android音频焦点Audio Focus
为了便于理解,我们以android的8.0以前的版本为例,8.0以后有一定改动,但是基本思路一样. 关于管理音频焦点(8.0以前和更高版本)的官方文档:https://developer.androi ...
- Android开发之Audio播放:竞争Audio之Audio Focus的应用
Android是多任务系统,Audio系统是竞争资源.Android2.2之前,没有内建的机制来解决多个程序竞争Audio的问题,2.2引入了称作AudioFocus的机制来管理对Audio资源的竞争 ...
- Android Audio Play Out Channel
1: 7嘴8舌 扬声器, 耳机, 和听筒 就是通过: audiomanager.setmode(AudioManager.MODE_IN_COMMUNICATION) audiomanager.set ...
- 【Android Audio】dumpsys audio分析【不定期更新文章】
dumpsys audio 显示当前所有stream type的音量状态 显示AudioDeviceBroker状态 命令: dumpsys audio Message handler (watch ...
- .Audio Focus机制以及AudioManager的使用
原文地址:http://tanxiaoya105.blog.163.com/blog/static/210328019201272295457523/ 大纲: 一.介绍Audio Focus机制 二. ...
- 音频焦点 (audio focus)(二)
什么叫音频焦点 (audio focus)? android系统是一个多任务操作系统,因此同一时刻允许许多任务同时工作.但是这对音频类应用来说是个挑战,因为如果多个音频同时播放的话,很多情况下用户体验 ...
- Managing Audio Playback之Managing Audio Focus
同一时间可能要好多个app在播放audio,Android用audio focus 来避免app之前互相影响.只有持有audio focus的app才可以播放audio. 可以用requestAudi ...
- <一>Android Audio音频框架
目录 1.0 设备驱动 2.0 android hal层 3.0 选择设备的暗箱策略AudioPolicy 4.0 软件层面的混音,AudioFlinger 5.0 完整的对外接口 AudioS ...
最新文章
- Tomcat 集群问题
- 好用的工具---screen命令
- E:Tree Queries(假树链剖分写法)
- 漫画:什么是自动驾驶?
- 浏览器从输入URL到页面渲染过程 ——页面渲染流程
- 带有MySQL和Bootstrap的Django 3教程和CRUD示例
- 河南成考计算机专业学校,河南成考能报哪个大学
- 押错宝!一次性将百万行代码从 Flow 迁移至 TypeScript
- H3C 路由器的IPSEC ××× 配置
- ascll编码表图片_ASCII码一览表,ASCII码对照表
- 关于dell电脑没有声音
- 蓝桥基础练习 杨辉三角形 JAVA
- 彻底删除手机系统软件
- C# LISTVIEW实例:文件图标显示
- 网站被黑的10大原因
- [Filecoin]协议实验室关于SNARK竞赛的公告
- HEU The message
- PS绘画效果滤镜Snap Art 4
- 关于echarts套娃柱状图(嵌套柱)的实现
- 说出数据连接池的工作机制是什么?