音频焦点整理

音频焦点总结

参考很多大神们的资料,再次表示感谢,

什么叫音频焦点 (audio focus)?

android系统是一个多任务操作系统,因此同一时刻允许许多任务同时工作。但是这对音频类应用来说是个挑战,因为如果多个音频同时播放的话,很多情况下用户体验会相当的差!比如听音乐时,来了个电话,这时你的耳机里就是电话和音乐共同工作,绝对是个悲剧!

为了解决这个问题从android2.2开始引入audio focus的概念。为避免多个音乐 App 在同时请求音频播放的时候发生冲突,Android 平台使用了音频焦点这一概念来协调音频播放——即只有获得音频焦点的 App 才可以播放音频。

AudioFocus是一个没有优先级概念的抢占式的机制。在一般情况下后一个申请者都能从前一个申请者的手中获取AudioFocus。不过只有一个例外,就是通话。通话作为手机的首要功能,同时也是一种音频的播放过程,所以从来电铃声开始到通话结束这个过程,Telephony相关的模块也会申请AudioFocus,但是它的优先级是最高的。Telephony可以从所有人手中抢走AudioFocus,但是任何人无法从它手中将其夺回。

值得一提的是,AudioFocus机制完全是一个建议性而不是强制性的机制。也就是说,上述的行为是建议回放实例遵守,而不是强制的。所以,市面上仍有一些带有音频播放功能的应用没有采用这套机制。

在应用开始播放音频之前,它需要首先请求并获得音频焦点。同时,App 应该能监听失去音频焦点事件,并做出相应的处理。

开始播放前必须要获取需要处理的音频流的音频焦点。实现音频焦点监听器OnAudioFocusChangeListener,这个监听器会根据当前音频焦点的变化,调用onAudioFocusChange(int focusChange)方法,focusChange主要有以下四种参数:

1、AUDIOFOCUS_GAIN:你已经获得音频焦点;

2、AUDIOFOCUS_LOSS:你已经失去音频焦点很长时间了,必须终止所有的音频播放。因为长时间的失去焦点后,不应该在期望有焦点返回,这是一个尽可能清除不用资源的好位置。例如,应该在此时释放MediaPlayer对象;

3、AUDIOFOCUS_LOSS_TRANSIENT:这说明你临时失去了音频焦点,但是在不久就会再返回来。此时,你必须终止所有的音频播放,但是保留你的播放资源,因为可能不久就会返回来。

4、AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:这说明你已经临时失去了音频焦点,但允许你安静的播放音频(低音量),而不是完全的终止音频播放。目前所有的情况下,onFocusChange的时候停止mediaPlayer

获取方法: requestAudioFocus()方法获得

获取成功:音频焦点成功获取后,该方法会返回 AUDIOFOCUS_REQUEST_GRANTED常量否则,会返回 AUDIOFOCUS_REQUEST_FAILED 常量。

需要指定进行操作的音频流,并确定要获取短暂的还是长期的音频焦点。短暂的音频焦点用于处理播放短时间的音频(例如汽车导航仪的提示)。如果您想长时间播放音频(例如播放音乐),那么就需要请求长期的音频焦点。

获得音频焦点的请求应该在马上就要播放音频前发出,比如在用户按下播放键或下一关游戏的背景音乐就要开始时发出焦点请求,接着再播放音乐。

AudioManager am = mContext.getSystemService( Context.AUDIO_SERVICE);

//请求播放的音频焦点

int result = am.requestAudioFocus(afChangeListener,

// 指定所使用的音频流

AudioManager.STREAM_MUSIC,

// 请求长时间的音频焦点

AudioManager.AUDIOFOCUS_GAIN);

if(resul==AudioManager.AUDIOFOCUS_REQUEST_GRANTED){

am.unregisterMediaButtonEventReceiver( RemoteControlReceiver;

//开始播放

}

当完成音频播放后,请一定记得调用 abandonAudioFocus()方法,这会通知系统您的App不再需要音频焦点,并移除相关 OnAudioFocusChangeListener 的注册。如果释放的是短暂音调焦点,那么被打断的音频会被继续播放。

// 当播放结束,您需要释放音频焦点

am.abandonAudioFocus(afChangeListener);

当请求短暂音频焦点时,您可以添加有一额外的选择——是否使用“浮动声音(英文为“ducking”,这里是指降低原音频流播放的音量,并使获得短暂音频焦点的音频流音量较大,而不去停止原来音频流的播放)”方式。

通常来说,一个好的音频播放App 会在失去音频焦点时立即停止播放。但如果在请求短暂音频焦点时使用“浮动声音”方式,可以允许先前的App以较低的音量继续播放,在重新获得音频焦点后再以原来的音量播放。

// 请求播放的音频焦点

int result = am.requestAudioFocus(afChangeListener,

// 指定所使用的音频流

AudioManager.STREAM_MUSIC,

// 请求短暂焦点

AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

if (result ==  AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {

// 开始播放

}

浮动音频非常适合间断播放音频的 App,例如导航仪的提示。当其他 App 通过上述方式请求音频焦点时,您所注册的监听器可以判断是否获得到了长期或短暂(可以选择浮动音频方式)的音频焦点。

对丢失音频焦点进行处理

App 请求并得到音频焦点后,当其他 App 请求得到焦点时,先前的 App 就会失去焦点。您的App 需要根据失去音频焦点的不同方式进行相应处理。

请求音频焦点时注册的音频焦点监听器中有 onAudioFocusChange(int)回调函数,该回调函数会接收描述焦点变化事件的参数。需要注意的是,失去音频焦点的事件类型与请求焦点的类型相对应——失去长期焦点(AUDIOFOCUS_LOSS)、短暂焦点(AUDIOFOCUS_LOSS_TRANSIENT)和浮动音频方式的短暂焦点(AUDIOFOCUS_LOSS_TRANSIENT)。

一般情况下,App 在失去短暂音频焦点时,应该停止播放并记录下播放状态。但仍然需要监听音频焦点的变化,当重新获得音频焦点时,需要在从先前暂停的地方继续播放。

如果失去的是长期音频焦点,那就是说其他App需要使用当前音频流,而您的App需要尽快结束。实际上,意味着您的App需要停止播放,移除媒体监听器并释放音频焦点——这将允许新的音频播放器独占地持有音频焦点等。这样一来,只有当用户执行了新的操作(如点击 App 中的播放按钮),才可以重新播放音频。

当 App 失去短暂的音频焦点时会暂停播放,当重新获得焦点时会继续播放。当失去的是长期音频焦点时,就会取消媒体按键事件接收器的注册并停止对音频焦点变化的监听。

OnAudioFocusChangeListener am = new  OnAudioFocusChangeListener() {

public  void onAudioFocusChange( int focusChange) {

if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT){

// 暂停播放

}  else  if (focusChange ==  AudioManager.AUDIOFOCUS_GAIN) {

// 恢复播放

}  else  if (focusChange ==  AudioManager.AUDIOFOCUS_LOSS) {

am.unregisterMediaButtonEventReceiver( RemoteControlReceiver);

am.abandonAudioFocus(afChangeListener);

// 停止播放

}

}

}

如果失去的是短暂且允许使用浮动播放(duck)的音频焦点,相比暂停播放,更好的做法应该是使用“浮动播放”的方式。

浮动播放( Duck)

浮动播放会将您正使用的音频流输出音量降低,这会使其他 App 的短暂音频更容易听到,如此一来您的 App 就不用被完全打断了。

下面的代码会使 App 在暂时失去焦点时降低媒体播放器的音量,并在重新获得音频焦点时恢复到原来的音量大小。

OnAudioFocusChangeListeneam=new OnAudioFocusChangeListener(){

public  void onAudioFocusChange( int focusChange) {

if(focusChange== AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {

// 降低音量

}  else  if (focusChange ==  AudioManager.AUDIOFOCUS_GAIN) {

// 恢复至正常音量

}

}

};

失去音频焦点的广播是需要响应的重要广播之一。系统会广播一系列 intent 对象来提醒您需要对用户的音频体验进行调整。

使用Audio的程序要做到:

使用前,用requestAudioFocus()申请AudioFocus,并根据应用的实际选取恰当的durationHint值;正确的在AudioManager.OnAudioFocusChangeListener中响应AudioFocus失去和重新获取事件;Audio使用结束,用abandonAudioFocus()归还AudioFocus。

时间: 2024-10-14 22:27:04

音频焦点整理的相关文章

管理音频焦点

由于可能会有多个应用可以播放音频,所以我们应当考虑一下他们应该如何交互.为了防止多个音乐播放应用同时播放音频,Android使用音频焦点(Audio Focus)来控制音频的播放--即只有获取到音频焦点的应用才能够播放音频. 在我们的应用开始播放音频之前,它需要先请求音频焦点,然后再获取到音频焦点.另外,它还需要知道如何监听失去音频焦点的事件并对此做出合适的响应. 请求获取音频焦点(Request the Audio Focus) 在我们的应用开始播放音频之前,它需要获取将要使用的音频流的音频焦

Android多媒体-MediaPlayer唤醒锁及音频焦点

MediaPlayer的唤醒锁 一般使用MediaPlayer播放音频流,推荐使用一个Service来承载MediaPlayer,而不是直接在Activity里使用.可是Android系统的功耗设计里,为了节约电池消耗,假设设备处于睡眠状态.系统将试图减少或者关闭一些没设备必须的特性.包含CUP和Wifi硬件.然后,假设是一个后台播放音乐的应用,减少CUP可能导致在后台执行的时候干扰音频的正常播放.关闭Wifi将可能导致网络音频流的获取出现错误. 为了确保MediaPlayer的承载的服务在系统

android 音频焦点

音频焦点分为两种 1永久占用((AudioManager) getSystemService(AUDIO_SERVICE)) .requestAudioFocus(null, AudioManager.STREAM_MUSIC,                AudioManager.AUDIOFOCUS_GAIN); 2临时占用((AudioManager) getSystemService(AUDIO_SERVICE)) .requestAudioFocus(null, AudioManag

Android开发之Mediaplayer状态转换图及音频焦点

前言 之前博客里已经将了MediaPlayer的简单应用,如何使用MediaPlayer在Android应用中播放音频.这篇博客在MediaPlayer使用的基础上,讲解一下MediaPlayer的一些高级功能的使用,以及它的状态转换.对MediaPlayer还不了解的朋友可以先看看之前那篇博客:Android--MP3播放器MediaPlayer. 本篇博客主要内容如下: MediaPlayer的状态变换 MediaPlayer的唤醒锁 MediaPlayer的音频焦点 MediaPlayer

关于音频焦点的理解

什么叫音频焦点 (audio focus)?  android系统是一个多任务操作系统,因此同一时刻允许许多任务同时工作.但是这对音频类应用来说是个挑战,因为如果多个音频同时播放的话,很多情况下用户体验会相当的差!比如听音乐时,来了个电话,这时你的耳机里就是电话和音乐共同工作,绝对是个悲剧!  为了解决这个问题从android2.2开始引入audio focus的概念.当你需要播放音乐或者发送一个通知的时候,你可以去要求获得音频焦点.一旦获得,就可以自由的使用音频输出设备.但是同时它也在时时刻刻

管理音频播放(摘自Android官方培训课程中文版(v0.9.5))

编写:kesenhoo - 原文:http://developer.android.com/training/managing-audio/index.html 如果我们的应用能够播放音频,那么让用户能够以自己预期的方式控制音频是很重要的.为了保证良好的用户体验,我们应该让应用能够管理当前的音频焦点,因为这样才能确保多个应用不会在同一时刻一起播放音频. 在学习本系列课程中,我们将会创建可以对音量按钮进行响应的应用,该应用会在播放音频的时候请求获取音频焦点,并且在当前音频焦点被系统或其他应用所改变

音频焦点问题

当我们在settings中试听铃声,这时候突然来了一个电话,那么会出现试听铃声和来电铃声同时播放的情况.当然,此情况同样适用于闹钟铃声,媒体音乐播放等.那么怎么解决这个问题呢?这就需要当音频焦点.---> 因为系统中可能会有多个应用程序会播放音频,所以需要考虑他们之间该如何交互,为了避免多个应用程序同时播放音乐,Android 系统使用音频焦点来进行统一管理,即只有获得了音频焦点的应用程序才可以播放音乐. 您的应用程序在开始播放音频文件前,首先应该请求获得音频焦点,并且应该同时注册监听音频焦点的

【Android应用开发技术:媒体开发】音频

作者:郭孝星 微博:郭孝星的新浪微博 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells Github:https://github.com/AllenWells Android为播放音乐.闹铃.通知铃.来电声音.系统声音.打电话声音和DTMF频道都分别维护了一个隔离的音频流,这是我们能够控制不同音频的前提,这其中大多数的音频流都是被系统限制的,不能胡乱使用. 一 音频控制 默认情况下,按下音量控制键会调节当前被激活的音频流,如果我们的

Xamarin的播放音频和视频的媒体管理插件

媒体应用程序比其他应用程序更受益于与本地平台一起工作.有些事情,比如处理音频焦点的中断.网络连接以及通知和其他回放控件之间的通信,这是一件复杂的事情. 为使Xamarin开发访问这些本地平台的功能,我们决定建立一个跨平台的Xamarin插件,抽象了困难.我们使用诱饵和开关模式创建了一个可移植类库,它包含了本机代码的所有接口,在应用程序中共享基类,使你尽可能轻松地在你的手机应用程序中与音频和视频交互. Xamarin媒体管理插件 设计简单易用,具有以下特点: 从远程和本地源本地播放媒体文件 本地媒