Android是多任务系统,Audio系统是竞争资源。Android2.2之前,没有内建的机制来解决多个程序竞争Audio的问题,2.2引入了称作AudioFocus的机制来管理对Audio资源的竞争的管理与协调。本文主要讲解AudioFocus的使用。
按
照AudioFocus的机制,在使用Audio之前,需要申请AudioFocus,在获得AudioFocus之后才可以使用Audio;如果有别的
程序竞争你正在使用的Audio,你的程序需要在收到通知之后做停止播放或者降低声音的处理。值得指出的是,这种机制是需要合作完成的,需要所有使用
Audio资源的程序都按照这种机制来做,而如果有程序在它失去AudioFocus的时候仍然在使用Audio,AudioFocus拿它也没办法。而
这一点对于开放系统的Android来说很致命的:用户可能安装没遵守这种机制的程序,或者版本太老还没引入这种机制的程序,这最终会导致很差的用户体
验。
对于手机方案公司来说,要做的能做的事情就是教育和培训团队成员以保证自己内建的程序遵守机制没问题,这包括了Android原生的程序、自己开发的程序,以及适配第三方的程序。
一、AudioFocus的申请与释放
下面看与AudioFocus的相关的类:
获取/放弃AudioFocus的方法都在android.media.AudioManager中,获取AudioFocus用requestAudioFocus()
;用完之后,放弃AudioFocus,用abandonAudioFocus()
。
其中,参数
:
返回值
,可能是:
二、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
-
-
} else
if
(focusChange == AudioManager.AUDIOFOCUS_LOSS) {
-
am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
-
am.abandonAudioFocus(afChangeListener);
-
-
} else
if
(focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
-
-
} else
if
(focusChange == AudioManager.AUDIOFOCUS_GAIN) {
-
-
}
-
}
-
};
三、典型的应用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()获取AudioFocus [Step#3]
- AudioFocus
Client失去了Audio
Focus,在onAudioFocusChanged()中,根据focusChange【focusChange的值与Other
App申请时的durationHint相反,即focusChange =
-1*durationHint】的值,做第二节中所描述的处理[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相关的测试,应该也没问题。
使用Audio的程序要做到:
问题点以及进一步的探讨
-
内部裁决机制怎样的?
-
申请的不同
Audio Stream
之间是不存在竞争的吗?
【更新】
1.
AudioFocus中虽然把AudioStream作为参数,但是AudioFocus的内部裁决机制并未针对AudioStream做什么特别的处
理。AudioFocus的处理针对所有的申请者来说的,除了它自身内部作为Alert的申请者有点特殊外,其它一律平等。所以文中,去掉
AudioStream的描述。
2. 阅读AudioFocus内部实现机制后,对一些描述更加明确化。
分享到:
相关推荐
4. 变更AudioFocus:当其他应用请求AudioFocus或系统状态改变(如来电)时,已拥有AudioFocus的应用会接收到onAudioFocusChange()的回调,告知其AudioFocus已被抢占或改变,需要做出相应调整,如暂停播放或降低音量...
- `AUDIOFOCUS_LOSS_TRANSIENT`:短暂失去焦点,比如用户短暂接收通知或语音命令,此时应用应暂停播放,但保留播放状态,以便恢复。 - `AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK`:可以降低音量继续播放,比如电话铃声...
7. **AudioFocus**:音频焦点管理是Android中处理多个应用同时播放音频时的重要机制。一个应用在请求音频焦点后才能播放音频,而其他应用则可能需要暂停或降低音量。 8. **AudioSession**:每个音频流都有一个唯一...
当多个应用同时播放音频时,Android会管理音频焦点。你可以通过实现`AudioManager.OnAudioFocusChangeListener`来请求和处理音频焦点: ```java AudioManager audioManager = (AudioManager) getSystemService...
1. **Android AudioFocus**:AudioFocus是Android系统中处理音频流之间竞争的一种机制。当多个应用同时尝试播放音频时,AudioFocus确保只有一个应用能成为“聚焦”应用,从而保证音频质量不被互相干扰。音乐播放器...
此外,Android 6.0引入了Audio Focus(音频焦点)的概念,它允许应用程序管理音频的播放和暂停,以避免多个应用同时播放音频造成冲突。例如,当电话响起时,正在播放的音乐应用会自动降低音量或暂停播放。实现音频...
2. AudioFocus:处理播放过程中的音频焦点问题,确保在切换应用或接听电话时能正确处理音频流。 3. Service:在后台持续运行,负责音乐的播放,即使用户离开应用也能继续播放。 三、音乐数据管理 1. 数据库:可能...
AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) .setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() { @...
AudioFocus管理音频流之间的相互影响,确保音频播放的顺畅。 三、视频处理 VideoView和MediaPlayer协同工作,可以轻松实现视频播放。对于更复杂的视频操作,如裁剪、合并或特效添加,开发者需要使用MediaCodec和...
在Android系统中,AudioFocus是一项关键功能,它确保了多个音频播放应用之间的和谐共存,避免音效互相干扰。当一个应用获取到AudioFocus时,它可以以正常音量播放音频,而其他应用则会降低音量或暂停播放,以确保...
11. **音频焦点管理**:在Android系统中,当多个应用尝试播放音频时,需要通过AudioFocus来管理哪个应用应该获得音频输出。音乐播放器需要正确处理音频焦点的变化,例如在电话来电时暂停播放。 12. **事件监听和回...
这个名为"Android应用源码之安卓视音频播放测试工程"的压缩包文件提供了一个实际的案例,可以帮助开发者深入理解如何在Android环境中实现多媒体播放功能。以下是这个项目中涉及的关键知识点: 1. **多媒体框架**:...
2. **AudioFocus**:在Android中,为了保证多个应用之间的音频播放和谐,需要处理音频焦点。MSD音乐播放器可能会实现AudioManager.OnAudioFocusChangeListener接口,监听音频焦点的变化,根据变化情况决定是否暂停或...
- AudioFocus:为了实现良好的用户体验,播放器需要处理音频焦点,确保在来电或其它应用需要音频时能够正确处理。 3. **用户界面设计** - Material Design:晴天播放器可能采用了Material Design设计语言,提供...
`AUDIOFOCUS_LOSS`意味着永久失去焦点,`AUDIOFOCUS_LOSS_TRANSIENT`表示暂时失去焦点,通常发生在用户按下HOME键或接到来电时,而`AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK`则允许应用在低音量下继续播放,比如背景音乐...
`AudioFocus`接口和`requestAudioFocus()`方法用于请求和管理音频焦点。音量控制则通过`AudioManager`的`adjustVolume()`和`setStreamVolume()`等方法实现。 五、实时通信和低延迟音频 对于实时通信应用,如VoIP和...
音频小偷Gradle// app/build.gradledependencies { implementation ' com.github.takusemba:audiothief:x.x.x '}特征 由于多个应用程序可以同时将音频播放到样本输出流,因此需要正确处理AudioFocus。 但是,您不想...
3. AudioFocus:处理播放音频时的音频焦点,确保音乐播放不会与其他应用冲突。 四、音频数据处理 1. MediaMetadataRetriever:获取音频文件的元数据,如艺术家、专辑、时长等,用于UI显示。 2. AudioEffect:处理...
2. **AudioFocus**:在播放音频时,需要处理音频焦点,确保在电话、其他音频应用等干扰下能正确处理播放状态。 3. **Service**:为了在后台持续播放音频,可能会创建一个Background Service,即使用户离开应用,音乐...
在Android开发中,WebView是一个非常重要的组件,它允许我们在原生应用中加载和展示网页内容。本教程将详细讲解如何使用WebView播放网络视频,并实现全屏显示,同时解决在5.0及以上系统上的声音问题以及全屏时的声音...