视频讲解:http://www.eyeandroid.com/thread-15896-1-1.html
由于很多应用程序都可以播放音频,因此在播放前考虑它们如何交互就显得很重要了,为了避免同时出现多个声音,Android使用音频焦点(AudioFocus)来控制音频的播放 - 仅仅是获取到Audio Focus的应用程序才能够播放音频。
在应用程序开始播放音频之前,它需要经过发出请求[request]à接受请求[receive] à音频焦点锁定[AudioFocus]的过程。同样它需要知道如何监听音频焦点的丢失并进行合适的响应。
请求获取音频焦点
在开始播放音频之前,应用程序必须先获取需要处理的音频流的音频焦点。音频焦点可以通过requestAudioFocus()方法获得,在音频焦点成功获取后,该方法会返回AUDIOFOCUS_REQUEST_GRANTED常量,否则会返回AUDIOFOCUS_REQUEST_FAILED常量。
我们必须指定正在使用的是哪个音频流,而且是否想请求短暂还是永久的Audio Focus。短暂的焦点锁定:当期待播放一个短暂的音频的时候(比如播放导航指示);永久的焦点锁定:当计划播放可预期到的较长的音频的时候(比如播放音乐)。
下面是一个在播放音乐的时候请求永久音频焦点的例子,我们必须在开始播放之前立即请求音频焦点,比如在用户点击播放或者游戏程序中下一关开始的片头音乐。
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.registerMediaButtonEventReceiver(RemoteControlReceiver);
// Start playback.
}
一旦结束了播放,需要确保调用abandonAudioFocus()方法。这样会通知系统说你不再需要获取焦点并且取消注册AudioManager.OnAudioFocusChangeListener的监听。如果是释放短暂音频焦点的情况下,可以让之前被打断的应用程序继续播放。
// Abandon audio focus when playback complete
am.abandonAudioFocus(afChangeListener);
当请求短暂音频焦点的时候,我们可以选择是否开启“ducking”。Ducking是一个特殊的机制使得允许音频间歇性的短暂播放。
通常情况下,一个好的应用程序在失去音频焦点的时候它会立即保持安静。如果我们选择在请求短暂音频焦点的时候开启了ducking,那意味着其它应用程序可以继续播放,仅仅是在这一刻降低自己的音量,在重新获取到音频焦点后恢复正常音量(也就是说:不用理会这个短暂焦点的请求,这并不会导致目前在播放的音频受到牵制,比如在播放音乐的时候突然出现一个短暂的短信提示声音,这个时候仅仅是把播放歌曲的音量暂时调低,好让短信声能够让用户听到,之后立马恢复正常播放)。
// 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.
}
Ducking非常适合间歇性播放音频的应用程序,例如播放导航仪的提示。
当其他应用程序通过上述方式请求音频焦点时,您所注册的监听器可以判断是否获丢失了长期或短暂(可以选择是否支持Ducing)的音频焦点。
处理失去音频焦点
应用程序请求并得到音频焦点后,当其他应用程序请求焦点时,先前的应用程序就会失去焦点。您的应用程序需要根据失去音频焦点的类型来进行相应的处理。
请求音频焦点时注册的音频焦点监听器中有onAudioFocusChange(int)回调函数,该回调函数会接收描述焦点变化事件的参数。需要注意的是,失去音频焦点的事件类型与请求焦点的类型相对应——失去长期焦点(AUDIOFOCUS_LOSS)、短暂焦点(AUDIOFOCUS_LOSS_TRANSIENT)和Ducking方式的短暂焦点(AUDIOFOCUS_LOSS_TRANSIENT)。
失去短暂焦点:一般情况下,应用程序在失去短暂音频焦点时,应该停止播放并记录下播放状态。而且需要继续监听音频焦点的变化,当重新获得音频焦点时,需要在从先前暂停的地方继续播放。
失去永久焦点:假设另外一个程序开始播放音乐等,那么我们的程序就应该有效的结束自己。实用的做法是停止播放,移除Media Button监听广播,允许新的音频播放器独占监听那些按钮事件,并且放弃自己的音频焦点。
在下面的代码中,当应用程序失去短暂的音频焦点时会暂停播放,当重新获得焦点时会继续播放。当失去的是长期音频焦点时,就会取消媒体按键事件接收器的注册并停止对音频焦点变化的监听。
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
}
}
};
在上面失去短暂焦点的例子中,如果允许ducking,那么我们可以选择“duck”的行为而不是暂停当前的播放。
闪避
Ducking是一个特殊的机制使得允许音频间歇性地短暂播放。在Ducking的情况下,正常播放的歌曲会降低音量来凸显这个短暂的音频声音,这样既让这个短暂的声音比较突出,又不至于打断正常的声音。
下面的代码会使应用程序在暂时失去焦点时降低媒体播放器的音量,并在重新获得音频焦点时恢复到原来的音量大小。
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
}
}
};
监听失去音频焦点是最重要的广播之一,但不是唯一需要监听的广播。系统广播了一系列的intent来警示你去改变用户的音频使用体验。下节课会演示如何监视那些广播来提升用户的整体体验。
分享到:
相关推荐
Android audio stack Applications MediaPlayer Media Recorder Audio Flinger iaudio 3@2011 Wolfson Microelectronics plc April2011www.wolfsonmicro.com V. wolfson Modern smartphone audio subsystems HDM ...
Managing user-initiated events such as touches and gestures Recording and playing audio and video Using hardware APIs available on Android devices Interacting with other devices via SMS, web browsing,...
Android Studio 3.2 Development Essentials – Kotlin Edition 版本: Developing Android 9 Apps Using Android Studio 3.2, Kotlin and Android Jetpack By 作者: Neil Smyth ISBN-10 书号: 0960010939 ISBN-13 ...
VTK 10 Managing Pipeline__ Execution.pdf VTK 10 Managing Pipeline__ Execution.pdf VTK 10 Managing Pipeline__ Execution.pdf
Rex Black's Managing the Testing Process, a compendium of real-world advice on managing software testing successfully. It is a veritable hodge-podge of sample test documents and is filled with ...
#### 8.2 设置无盘客户端 设置无盘客户端需要完成一系列步骤,包括配置网络参数、安装启动程序等。正确的设置是确保无盘客户端正常工作的关键。 #### 8.3 无盘客户端引导过程 无盘客户端的引导过程与普通客户端...
The Android Developer's Cookbook Building Applications with the Android SDK and Source Project Code 源书(pdf)及源代码12章全都有(rar) Book Description Want to get started building applications for ...
In RTP: Audio and Video for the Internet, Colin Perkins, a leader of the RTP standardization process in the IETF, offers readers detailed technical guidance for designing, implementing, and managing ...
综上所述,这个插件的核心是将YOLOv5的目标检测能力引入到Flutter应用中,允许开发者在iOS和Android平台上实现图像和视频的目标检测功能。通过这个插件,开发者可以轻松地加载和运行预训练的YOLOv5模型,用于识别和...
### DB2 Command Reference Version 8.2:关键知识点解析 #### 概述 DB2是IBM推出的一款功能强大且高效的关系型数据库管理系统(RDBMS)。《DB2 Command Reference version 8.2》文档详细介绍了DB2 Version 8.2版本...
Managing Gigabytes 很经典的关于大数据处理的书籍,废了很大力气转成pdf 编辑了目录。
Chapter 1: Hello, Android A Little Background What Android Isn't Android: An Open Platform for Mobile Development Native Android Applications Android SDK Features Introducing the Open Handset Alliance...
Android library for managing and applying multiple defined R.style.Theme.... themes at runtime for dyanically changing the look and feel of your application Demo Installation Add this line to your...
**《Managing Your Biological Data with Python》**是一本专注于生物数据管理与分析的指南性书籍,它属于**CHAPMAN & HALL/CRC Mathematicaland Computational Biology Series**系列。该系列旨在捕捉数学与计算生物...
Master game development with the Android SDK to develop highly interactive and amazing games About This Book Develop complex Android games from scratch Learn the internals of a game engine by ...
A library managing nested Fragment, translucent StatusBar and Toolbar for Android. You could use it as a single Activity Architecture Component. This is also the subproject of react-native-...