什麼叫音頻焦點 (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 這個參數一開始沒理解有什麼做用,就沒寫。直到發現,個人音樂播放器在我已經手動暫停的狀況下,老是在我打完電話後自動播放音樂,才發現他的做用。打完電話,手機就這麼一路唱着歌在個人口袋裏二逼呵呵的歡樂着。本身還不知道,等再要用手機的時候發現電都被搞掉了很多,且無數人側目看我是一個怎樣的二貨喜歡外放音樂.....慶幸手機裏沒有鳳凰傳奇的歌曲。
其實這個參數的做用就是可讓播放器僅僅在短暫失去音頻焦點並從新得到後纔開始播放音樂。而不是任什麼時候候從新得到焦點都開始播放。