《Android优化专题》——音频播放
一、控制app的音量与播放
使用硬件音量键来控制音量
需要在Activity或者Fragment创建的时候就设置音量控制,这样确保不管App是否可见,音频控制功能都正常工作。
1 | setVolumeControlStream(AudioManager.STREAM_MUSIC); |
使用硬件的播放控制按键来控制App的音频播放
无论用户通过手机或者线控耳机等按下哪些控制按钮,比如播放、暂停,系统都会广播一个带有ACTION_MEDIA_BUTTON的Intent。
1 | <receiver android:name=".RemoteControlReceiver"> |
Receiver需要判断广播来自哪个按钮
1 | public class RemoteControlReceiver extends BroadcastReceiver { |
如何注册监听和取消监听
1 | AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); |
二、管理音频焦点
请求获取音频焦点
requestAudioFocus() 来获取到音频流焦点。
- 短暂的焦点锁定:当期待播放一个短暂的音频时候(比如推送声音)
- 永久的焦点锁定:当计划播放可预期到的较长的音频时候(比如播放音乐)
我们必须在开始播放前请求音频焦点,比如用户此时点击了播放按钮
1 | AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE); |
一旦结束播放,需要调用abandonAudioFocus()方法,通知系统说不再需要获取焦点并且取消注册AudioManager.OnAudioFocusChangeListener的焦点。
1 | // Abandon audio focus when playback complete |
当请求短暂音频焦点,我们可以选择是否开启”ducking”,Ducking机制可以允许音频间歇性短暂播放。可以让其他App继续播放,仅在短暂的时间内降低自己的音量。
1 | // Request audio focus for playback |
处理失去音频焦点
- 失去短暂焦点:在这种情况下,暂停当前音频的播放或者降低音量,需要准备恢复播放在重新获取到焦点之后。
- 失去永久焦点:假设另一个程序开始播放音乐,此时我们的程序就应该彻底结束。停止播放,放弃自己的音频焦点。
- Ducking:降低音量,让其余短暂声音突出,之后恢复原音量。
1 | OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { |
三、音频设备的相关问题
检测目前正在使用的硬件设备
可以使用AudioManager来查询某个音频是否输出到扬声器,有线耳机还是蓝牙上。
1 | if (isBluetoothA2dpOn()) { |
处理音频输出设备的改变
当耳机线被拔出,或者蓝牙耳机连接断开时,如果在播放音乐/视频,为了用户体验,避免突如其来的扬声器播放,我们通常做法是暂停此时正在播放的音乐/视频。
在这种情况下,系统会广播带有ACTION_AUDIO_BECOMING_NOISY的intent。我们只需要接受这种广播,对其进行处理即可。
1 | private class NoisyAudioStreamReceiver extends BroadcastReceiver { |