视频讲解: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 Training视频系列] 8.2 Managing Audio Focus的更多相关文章

  1. [Android Training视频系列] 8.3 Dealing with Audio Output Hardware

    用户在播放音乐的时候有多个选择,可以使用内置的扬声器,有线耳机或者是支持A2DP的蓝牙耳机.(补充:A2DP全名是Advanced Audio Distribution Profile 蓝牙音频传输模 ...

  2. [Android Training视频系列] 8.1 Controlling Your App’s Volume and Playback

    主要内容:1 鉴别使用的是哪个音频流2 使用物理音量键控制应用程序的音量 3 使用物理播放控制键来控制应用程序的音频播放 视频讲解:http://www.eyeandroid.com/thread-1 ...

  3. Android Training

    Building Apps with Content Sharing Simple Data --> Intent && ActionProvider 介绍如何让应用程序共享简单 ...

  4. android音视频点/直播模块开发

      音视频 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白, ...

  5. (android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

    从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据 ...

  6. [Android 性能优化系列]降低你的界面布局层次结构的一部分

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地 ...

  7. Android libyuv应用系列(二)libyuv的使用

    上篇文章Android libyuv使用系列(一)Android常用的几种格式:NV21/NV12/YV12/YUV420P的区别中我们了解了YUV相关的知识,而本篇文章我会介绍libyuv是什么,以 ...

  8. Android 音视频同步机制

    一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...

  9. Android 音视频深入 七 学习之路的总结和资料分享

    说个实话一开始我对基于Android如何开发音视频很迷茫,甚至对音视频开发都不是很明白,我看了Android 音视频开发入门指南 http://blog.51cto.com/ticktick/1956 ...

随机推荐

  1. HTML常见元素集锦

    在讲解本次课程前:我们先来看下什么是浏览器: 所谓浏览器就是可以解释和执行HTML代码的工具.还有一个概念我们需要搞清楚,浏览器!=IE,IE只是浏览器当中的一种.除了IE还有N多浏览器,google ...

  2. Validform使用

    原文链接:http://validform.rjboy.cn/document.html Validform v5.3.2 文档 Validform使用入门 绑定附加属性 初始化参数说明 Validf ...

  3. Android IOS WebRTC 音视频开发总结(五九)-- webrtc这蛋糕都怎么吃?

    本文主要介绍webrtc应用状况,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com WebRTC是个好东东,就好比是 ...

  4. Large-Scale Named Entity Disambiguation Based on Wikipedia Data

    Large-Scale Named Entity Disambiguation Based on Wikipedia Data 基于维基百科数据的大规模命名实体消岐 1.引言 1.1. 概念 实体(e ...

  5. C puzzles详解【13-15题】

    第十三题 int CountBits(unsigned int x) { ; while(x) { count++; x = x&(x-); } return count; } 知识点讲解 位 ...

  6. s3c6410_uart初始化及读写

    参考: 1)<USER'S MANUAL-S3C6410X>第31章 UART 2)u-boot uart初始化及读写:u-boot-x.x.x/board/samsumg/smdk641 ...

  7. webservice安全性之 SoapHeader自定义身份验证

    相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了. 首先我们来介绍webservic ...

  8. 银河英雄传说 (codevs 1540) 题解

    [问题描述] 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰 ...

  9. xml结构

    一.XmlHelper using System; using System.Collections.Generic; using System.Linq; using System.Web; usi ...

  10. 使用WIF实现单点登录Part IV —— 常见问题

    InvalidOperationException: ID1073: 尝试使用 ProtectedData API 解密 Cookie 时出现 CryptographicException (有关详细 ...