什么是焦点?
焦点顾名思义就是聚集点,而我们今天要说到的是音频的焦点。音频的焦点说简单点,就是你能听见的音频的声音。
在安卓设备上默认是可以好多声音一起播放的,而加入了焦点机制,可以更加有序的对声音进行管理,从而提高了用户的体验感。
官网给出的大致步骤如下:
- 在开始播放之前,调用
requestAudioFocus()
方法,并检查返回值是否是AUDIOFOCUS_REQUEST_GRANTED,若成功获取,则开始播放。 - 当App失去音频焦点时,根据失去的焦点类型,应该暂停播放,或者将音量调低。
- 当播放结束时,释放音频焦点,
abandonAudioFocus()
。
相关音频焦点的处理方法
requestAudioFocus():用于申请音频焦点
abandonAudioFocus():用于释放音频焦点
AudioManager.OnAudioFocusChangeListener接口,提供了onAudioFocusChange()方法来监听音频焦点变化
使用场景举例
当播放一个视频的时候,这时你想让另一个语音播放,在播放语音的时候,视频声音是不播放的,但是视频是继续播放的,等语音播放完的时候,视频的声音播放。
具体使用规范
处理音频焦点都是通过AudioManager这个类。
1、首先我们得在播放视频的逻辑代码中国,获得一个AudioManager 实例,一般放在oncreate中实现。
AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
2、设置实现音频焦点监听器OnAudioFocusChangeListener,这个监听器会根据当前音频焦点的变化,调用onAudioFocusChange(intfocusChange)方法。
AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
//音频焦点切换
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
//完全获得了音频焦点, 重新获取audio focus,开始播放或者提高音量
break;
case AudioManager.AUDIOFOCUS_LOSS:
// 失去audio focus很长一段时间,必须停止所有的audio播放,清理资源
//onAudioFocusChange长时间失去音频焦点,停止播放或者降低音量,释放资源
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// 暂时失去audio focus,但是很快就会重新获得,在此状态应该暂停所有音频播放,但是不能清除资源
// if (mediaPlayer.isPlaying())
// mediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// 暂时失去 audio focus,但是允许持续播放音频(以很小的声音),不需要完全停止播放,也可降低音量。
break;
default:
break;
}
}
};
2、然后在视频播放的地方进行request请求,即申请获得音频焦点,一般在onprepare中,根据自己的情况而定。就在合适的地方,比如播放音乐的按钮中放置获得音频焦点的代码。哈哈哈,具体你自己定~~
mAudioManager.requestAudioFocus(mAudioFocusListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
这个方法有三个参数,接下来讲下他们分别代表的是什么意思
第一个参数 OnAudioFocusChangeListener:就是音频焦点变化时的监听器,这是音频焦点控制的重点。
第二个参数streamType:申请音频焦点处理的音频类型,这里是AudioManager.STREAM_MUSIC
- STREAM_MUSIC——音乐类
- STREAM_VOICE_CALL——通话
- STREAM_SYSTEM——系统
- STREAM_RING——电话铃声
- STREAM_ALARM——闹钟
- STREAM_NOTIFICATION——系统通知
- STREAM_DTMF——DTMF调音
他有好几个可选的。
第三个参数durationHint :告知系统,你要求获得音频焦点的用途,系统根据你所要求的类型来给其他监听者发出相应的焦点控制参数。有三种可选
AUDIOFOCUS_GAIN:我要求完全获得焦点,其他人需要释放焦点。比如我要播放音乐了,这时就要抢占整个音频焦点。
AUDIOFOCUS_GAIN_TRANSIENT:只是短暂获得,一会就释放焦点,比如你只是想发个notification时用下一秒不到的铃声。
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:只是背景获得,之前的音频焦点使用者无需释放焦点给我,我将与其共同使用。
二、在另一个短暂声音的功能类中,在其oncreate中进行注册
// 处理音频焦点-处理多个程序会来竞争音频输出设备
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 对于Android 8.0+
audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
.setOnAudioFocusChangeListener(mAudioFocusChangeListener).build();
audioFocusRequest.acceptsDelayedFocusGain();
}
具体功能地方进行以下代码的实现
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioManager.requestAudioFocus(audioFocusRequest);
Log.e(TAG, "请求音频焦点");
} else {
// 小于Android 8.0
int result = mAudioManager.requestAudioFocus(mAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// could not get audio focus.
}else {
}
}
记得一定要释放资源
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioManager.abandonAudioFocusRequest(audioFocusRequest);}else
{
mAudioManager.abandonAudioFocus(mAudioFocusChangeListener);
}