什么叫音频焦点 (audio focus)?android
android系统是一个多任务操做系统,所以同一时刻容许许多任务同时工做。可是这对音频类应用来讲是个挑战,由于若是多个音频同时播放的话,不少状况下用户体验会至关的差!好比听音乐时,来了个电话,这时你的耳机里就是电话和音乐共同工做,绝对是个悲剧!this
为了解决这个问题从android2.2开始引入audio focus的概念。当你须要播放音乐或者发送一个通知的时候,你能够去要求得到音频焦点。一旦得到,就能够自由的使用音频输出设备。可是同时它也在时时刻刻的监听着音频焦点的变化。当音频焦点变化时,你须要去合适的处理你的音频输出。操作系统
音频焦点工做的示例:资源
第一步get
首先你要得到一个音频管理服务AudioManagerit
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);io
这个一般在service的oncreate中完成。stream
第二步音频
而后在合适的地方,好比播放音乐的按钮中放置得到音频焦点的代码用户体验
mAudioManager.requestAudioFocus(mAudioFocusListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
requestAudioFocus方法能够得到音频焦点,其有三个参数,解释以下:
第一个参数 OnAudioFocusChangeListener:就是音频焦点变化时的监听器,这是音频焦点控制的重点。
第二个参数streamType:焦点得到以后的数据传输类型,这里是AudioManager.STREAM_MUSIC
第三个参数durationHint :告知系统,你要求得到音频焦点的用途,系统根据你所要求的类型来给其余监听者发出相应的焦点控制参数。有三种可选
AUDIOFOCUS_GAIN_TRANSIENT:只是短暂得到,一会就释放焦点,好比你只是想发个notification时用下一秒不到的铃声。
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:只是背景得到,以前的音频焦点使用者无需释放焦点给我,我将与其共同使用。
AUDIOFOCUS_GAIN:我要求彻底得到焦点,其余人须要释放焦点。好比我要播放音乐了,这时就要抢占整个音频焦点。
第三步
实现音频焦点监听器OnAudioFocusChangeListener,这个监听器会根据当前音频焦点的变化,调用onAudioFocusChange(int focusChange)方法,focusChange主要有如下四种参数:
AUDIOFOCUS_AGIN:你已经彻底得到了音频焦点
AUDIOFOCUS_LOSS:你会长时间的失去焦点,因此不要期望在短期内能得到。请结束本身的相关音频工做并作好收尾工做。好比另一个音乐播放器开始播放音乐了(前提是这个另外的音乐播放器他也实现了音频焦点的控制,baidu音乐,每天静听很遗憾的就没有实现,因此他们两个是能够跟别的播放器同时播放的)
AUDIOFOCUS_LOSS_TRANSIENT:你会短暂的失去音频焦点,你能够暂停音乐,但不要释放资源,由于你一会就能够夺回焦点并继续使用
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:你的焦点会短暂失去,可是你能够与新的使用者共同使用音频焦点
具体示例以下:
private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener(){
public void onAudioFocusChange(int focusChange) {
switch(focusChange){
case AudioManager.AUDIOFOCUS_LOSS:
if(isPlaying()){
//we do not need get focus back in this situation
//会长时间失去,因此告知下面的判断,得到焦点后不要自动播放
mPausedByTransientLossOfFocus = false;
pause();//由于会长时间失去,因此直接暂停
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
if(isPlaying()){
//短暂失去焦点,先暂停。同时将标志位置成从新得到焦点后就开始播放
mPausedByTransientLossOfFocus = true;
pause();
}
break;
case AudioManager.AUDIOFOCUS_GAIN:
//从新得到焦点,且符合播放条件,开始播放
if(!isPlaying()&&mPausedByTransientLossOfFocus){
mPausedByTransientLossOfFocus = false;
resume();
}
break;
}
}};
最后
在适当的时候注销掉这个监听器好比在onDestroy()中
mAudioManager.abandonAudioFocus(mAudioFocusListener);
到此整个音频焦点的控制就完成了
讲一个本身的故事,mPausedByTransientLossOfFocus 这个参数一开始没理解有什么做用,就没写。直到发现,个人音乐播放器在我已经手动暂停的状况下,老是在我打完电话后自动播放音乐,才发现他的做用。打完电话,手机就这么一路唱着歌在个人口袋里二逼呵呵的欢乐着。本身还不知道,等再要用手机的时候发现电都被搞掉了很多,且无数人侧目看我是一个怎样的二货喜欢外放音乐.....庆幸手机里没有凤凰传奇的歌曲。
其实这个参数的做用就是可让播放器仅仅在短暂失去音频焦点并从新得到后才开始播放音乐。而不是任什么时候候从新得到焦点都开始播放。