网站 后台,易语言怎么做点击按钮打开网站,wordpress 网址分享,大画册设计网站前言
前面写过一篇类似的文章#xff0c;没写完#xff0c;今天再详细描述一下。
Android音频焦点申请处理
音频焦点管理的意义
两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在一起。虽然这是一项出色的技术#xff0c;但却会给用…前言
前面写过一篇类似的文章没写完今天再详细描述一下。
Android音频焦点申请处理
音频焦点管理的意义
两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在一起。虽然这是一项出色的技术但却会给用户带来很大的困扰。为了避免所有音乐应用同时播放Android 引入了“音频焦点”的概念。 一次只能有一个应用获得音频焦点。
当您的应用需要输出音频时它需要请求获得音频焦点获得焦点后就可以播放声音了。不过在您获得音频焦点后您可能无法将其一直持有到播放完成。其他应用可以请求焦点从而占有您持有的音频焦点。如果发生这种情况您的应用应暂停播放或降低音量以便于用户听到新的音频源。
音频焦点管理的行为准则
在即将开始播放之前调用 requestAudioFocus()并验证调用是否返回 AUDIOFOCUS_REQUEST_GRANTED。在其他应用获得音频焦点时应该停止或者暂停播放或者降低音量。播放停止后应该放弃音频焦点
版本兼容
从Android 8.0(O版本API 26)开始音频焦点的请求方式以及系统管理有了细微的变化下面分两部分来说明。
在Android 8.0(API 26) 之前对音频焦点具体处理实现
当想录音或者播放歌曲的时候最好(非必须)先请求音频焦点这个时候需要调用AudioManager.requestAudioFocus()方法函数原型如下
AudioManager.requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
第一个参数用于监听焦点变化
第二个参数表明请求的音频焦点影响的是那种类型流例如如果我们录音我们肯定是要影响Music这一类型的音频流因此可以选择AudioManager.STREAM_MUSIC。当然还有许多类型
/** 通话相关 */
public static final int STREAM_VOICE_CALL AudioSystem.STREAM_VOICE_CALL;
/** 系统声音 */
public static final int STREAM_SYSTEM AudioSystem.STREAM_SYSTEM;
/** 铃声 */
public static final int STREAM_RING AudioSystem.STREAM_RING;
/** 音乐相关 */
public static final int STREAM_MUSIC AudioSystem.STREAM_MUSIC;
/** 闹钟相关 */
public static final int STREAM_ALARM AudioSystem.STREAM_ALARM;第三个参数用于表明音频焦点的持续时间这个很关键它也有许多种类型下面一一列出。
AudioManager.AUDIOFOCUS_GAIN: API文档说请求的这类音频焦点持续时间是未知的通常用来表示长时间获取焦点可以用来播放音乐录音等等。AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: 表明请求的音频焦点持续时间比较短通常用来播放导航路线的声音或者播放通知声音。AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: 这个也是表明请求的音频焦点持续时间比较短但是在这段时间内它希望其他应用以较低音量继续播放。例如我们在使用导航的时候可以听音乐当出现导航语音的时候音乐音量会降低以便我们能听清楚导航的语音当导航语音播放完毕后音乐恢复音量继续播放。AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 这个也是表明音请求的音频焦点持续时间比较短但是在这段时间内不希望任何应用(包括系统应用)来做任何与音频相关的事情就算是降低音量播放音乐也是不被希望的。例如当我们进行录音或者语音识别的时候我们不希望其他的声音出现干扰。
AudioManager.requestAudioFocus()的返回值表明请求的结果AudioManager.AUDIOFOCUS_REQUEST_FAILED表明请求焦点失败AudioManager.AUDIOFOCUS_REQUEST_GRANTED表明请求焦点成功。
当我们成功请求焦点后就可以做一些与音频有关的事情例如播放音乐录音或者语音识别。完成这些工作后我们必须调用AudioManager.abandonAudioFocus(onAudioFocusChangeListener l)释放音频焦点。
8.0 之后实现
从Android 8.0开始(API 26)请求音频焦点的方式以及系统对音频焦点变化的管理有些微妙的变化。 首先对音频焦点变化的管理的变化体现在两个方面延迟获取焦点和自动降低音量。
延迟获取焦点
在Android 8.0之前当我们请求音频焦点的时候只会返回两种结果要么请求成功(AUDIOFOCUS_REQUEST_GRANTED)要么请求失败(AUDIOFOCUS_REQUEST_FAILED)。
而从Android 8.0开始还有一种结果延迟成功请求(AUDIOFOCUS_REQUEST_DELAYED)这个也是成功的请求但是这个请求具有延迟性。例如当我们处于通话状态的时候我们很显然不希望任何app来获取到音频焦点来做些事例如播放音乐。
然而只有设置过AudioFocusRequest.Builder.setAcceptsDelayedFocusGain(true)才能获取到这种结果这个我们后面会讲到。那么我们怎么知道什么时候获取到了音频焦点呢当然还需要设置AudioManager.OnAudioFocusChangeListener这个音频焦点变化的监听器通过回调确认何时获取到了音频焦点。
自动降低音量
在Android 8.0之前如果请求焦点使用了AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK参数它表明希望拥有了音频焦点的其他应用降低音量来使用音频然而并不是所有的应用都会这样做(有可能开发者忘记了优化)因为这并不是系统强制的。但是, 从Android 8.0开始这个降低音量的工作就是系统默认行为了可以说是一个良心的优化。
如果我不希望系统自动给我降低音量而是想自己暂停音频相关的工作那咋办这个可以通过AudioFocusRequest.Builder.setWillPauseWhenDucked(true)方法取消系统的默认行为然后通过监听音频焦点变化
音频焦点请求方式
从 Android 8.0API 级别 26开始当您调用 requestAudioFocus() 时必须提供 AudioFocusRequest 参数。要释放音频焦点请调用 abandonAudioFocusRequest() 方法该方法也接受 AudioFocusRequest 作为参数。在请求和放弃焦点时应使用相同的 AudioFocusRequest 实例。
要创建 AudioFocusRequest请使用 AudioFocusRequest.Builder。由于焦点请求始终必须指定请求的类型因此此类型会包含在构建器的构造函数中。使用构建器的方法来设置请求的其他字段
setFocusGain(): 只有这个方法是必须的而传入的参数与8.0之前使用AudioManager.requestAudioFocus()传入的第三个参数一样都是用来表示持续时间。setAudioAttributes(): 这个方法是用来描述app的使用情况。这方法需要传入一个AudioAttributes对象这个对象也是使用Builder模式来构造例如使用AudioAttributes.Builder.setUsage()来描述使用这个音频来干什么我们可以传入一个AudioAttributes.USAGE_MEDIA来表明用这个音频来作为媒体文件来播放也可以传入一个AudioAttributes.USAGE_ALARM来表明用这个来作为闹铃。setWillPauseWhenDucked(): 这个前面说过是为了覆盖系统默认降低音量的行为但是必须要设置AudioManager.OnAudioFocusChangeListener才能自己处理这类情况。setAcceptsDelayedFocusGain(): 这个前面也说过这个是为了能够延迟获取到焦点的必须条件但是同时也必须要设置AudioManager.OnAudioFocusChangeListener才能得知何时获取到焦点。setOnAudioFocusChangeListener(): 音频焦点变化监听器。值得一提的是这个方法有个重载的方法有一个重载方法有两个参数第二个参数为Handler对象看到Handler应该明白了是为了使用它的消息队列来顺序处理这个回调
响应音频焦点更改
当应用获得音频焦点后它必须能够在其他应用为自己请求音频焦点时释放该焦点。出现这种情况时您的应用会收到对 AudioFocusChangeListener 中的 onAudioFocusChange() 方法的调用该方法是您在应用调用 requestAudioFocus() 时指定的。
传递给 onAudioFocusChange() 的 focusChange 参数表示所发生的更改类型。它对应于获取焦点的应用所使用的持续时间提示。您的应用应该做出适当的响应。
暂时性失去焦点
如果焦点更改是暂时性的AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 或 AUDIOFOCUS_LOSS_TRANSIENT您的应用应该降低音量如果您不依赖于自动降低音量或暂停播放否则保持相同的状态。
在暂时性失去音频焦点时您应该继续监控音频焦点的变化并准备好在重新获得焦点后恢复正常播放。当抢占焦点的应用放弃焦点时您会收到一个回调 (AUDIOFOCUS_GAIN)。此时您可以将音量恢复到正常水平或重新开始播放。
永久性失去焦点
如果是永久性失去音频焦点 (AUDIOFOCUS_LOSS)则其他应用会播放音频。您的应用应立即暂停播放因为它不会收到 AUDIOFOCUS_GAIN 回调。要重新开始播放用户必须执行明确的操作例如在通知或应用界面中按播放传输控件。