視頻講解:http://www.eyeandroid.com/thread-15896-1-1.htmlhtml
因爲不少應用程序均可以播放音頻,所以在播放前考慮它們如何交互就顯得很重要了,爲了不同時出現多個聲音,Android使用音頻焦點(AudioFocus)來控制音頻的播放 - 僅僅是獲取到Audio Focus的應用程序纔可以播放音頻。android
在應用程序開始播放音頻以前,它須要通過發出請求[request]à接受請求[receive] à音頻焦點鎖定[AudioFocus]的過程。一樣它須要知道如何監聽音頻焦點的丟失並進行合適的響應。函數
請求獲取音頻焦點spa
在開始播放音頻以前,應用程序必須先獲取須要處理的音頻流的音頻焦點。音頻焦點能夠經過requestAudioFocus()方法得到,在音頻焦點成功獲取後,該方法會返回AUDIOFOCUS_REQUEST_GRANTED常量,不然會返回AUDIOFOCUS_REQUEST_FAILED常量。orm
咱們必須指定正在使用的是哪一個音頻流,並且是否想請求短暫仍是永久的Audio Focus。短暫的焦點鎖定:當期待播放一個短暫的音頻的時候(好比播放導航指示);永久的焦點鎖定:當計劃播放可預期到的較長的音頻的時候(好比播放音樂)。視頻
下面是一個在播放音樂的時候請求永久音頻焦點的例子,咱們必須在開始播放以前當即請求音頻焦點,好比在用戶點擊播放或者遊戲程序中下一關開始的片頭音樂。htm
AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);遊戲 ...事件 // Request audio focus for playbackci int result = am.requestAudioFocus(afChangeListener,// Use the music stream. AudioManager.STREAM_MUSIC,// Request permanent focus. AudioManager.AUDIOFOCUS_GAIN); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { am.registerMediaButtonEventReceiver(RemoteControlReceiver); // Start playback. } |
一旦結束了播放,須要確保調用abandonAudioFocus()方法。這樣會通知系統說你再也不須要獲取焦點而且取消註冊AudioManager.OnAudioFocusChangeListener的監聽。若是是釋放短暫音頻焦點的狀況下,可讓以前被打斷的應用程序繼續播放。
// Abandon audio focus when playback complete am.abandonAudioFocus(afChangeListener); |
當請求短暫音頻焦點的時候,咱們能夠選擇是否開啓「ducking」。Ducking是一個特殊的機制使得容許音頻間歇性的短暫播放。
一般狀況下,一個好的應用程序在失去音頻焦點的時候它會當即保持安靜。若是咱們選擇在請求短暫音頻焦點的時候開啓了ducking,那意味着其它應用程序能夠繼續播放,僅僅是在這一刻下降本身的音量,在從新獲取到音頻焦點後恢復正常音量(也就是說:不用理會這個短暫焦點的請求,這並不會致使目前在播放的音頻受到牽制,好比在播放音樂的時候忽然出現一個短暫的短信提示聲音,這個時候僅僅是把播放歌曲的音量暫時調低,好讓短信聲可以讓用戶聽到,以後立馬恢復正常播放)。
// Request audio focus for playback int result = am.requestAudioFocus(afChangeListener,// Use the music stream. AudioManager.STREAM_MUSIC,// Request permanent focus. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback. } |
Ducking很是適合間歇性播放音頻的應用程序,例如播放導航儀的提示。
當其餘應用程序經過上述方式請求音頻焦點時,您所註冊的監聽器能夠判斷是否獲丟失了長期或短暫(能夠選擇是否支持Ducing)的音頻焦點。
處理失去音頻焦點
應用程序請求並獲得音頻焦點後,當其餘應用程序請求焦點時,先前的應用程序就會失去焦點。您的應用程序須要根據失去音頻焦點的類型來進行相應的處理。
請求音頻焦點時註冊的音頻焦點監聽器中有onAudioFocusChange(int)回調函數,該回調函數會接收描述焦點變化事件的參數。須要注意的是,失去音頻焦點的事件類型與請求焦點的類型相對應——失去長期焦點(AUDIOFOCUS_LOSS)、短暫焦點(AUDIOFOCUS_LOSS_TRANSIENT)和Ducking方式的短暫焦點(AUDIOFOCUS_LOSS_TRANSIENT)。
失去短暫焦點:通常狀況下,應用程序在失去短暫音頻焦點時,應該中止播放並記錄下播放狀態。並且須要繼續監聽音頻焦點的變化,當從新得到音頻焦點時,須要在從先前暫停的地方繼續播放。
失去永久焦點:假設另一個程序開始播放音樂等,那麼咱們的程序就應該有效的結束本身。實用的作法是中止播放,移除Media Button監聽廣播,容許新的音頻播放器獨佔監聽那些按鈕事件,而且放棄本身的音頻焦點。
在下面的代碼中,當應用程序失去短暫的音頻焦點時會暫停播放,當從新得到焦點時會繼續播放。當失去的是長期音頻焦點時,就會取消媒體按鍵事件接收器的註冊並中止對音頻焦點變化的監聽。
OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT // Pause playback } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { // Resume playback } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { am.unregisterMediaButtonEventReceiver(RemoteControlReceiver); am.abandonAudioFocus(afChangeListener); // Stop playback } } }; |
在上面失去短暫焦點的例子中,若是容許ducking,那麼咱們能夠選擇「duck」的行爲而不是暫停當前的播放。
閃避
Ducking是一個特殊的機制使得容許音頻間歇性地短暫播放。在Ducking的狀況下,正常播放的歌曲會下降音量來凸顯這個短暫的音頻聲音,這樣既讓這個短暫的聲音比較突出,又不至於打斷正常的聲音。
下面的代碼會使應用程序在暫時失去焦點時下降媒體播放器的音量,並在從新得到音頻焦點時恢復到原來的音量大小。
OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { // Lower the volume } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { // Raise it back to normal } } }; |
監聽失去音頻焦點是最重要的廣播之一,但不是惟一須要監聽的廣播。系統廣播了一系列的intent來警示你去改變用戶的音頻使用體驗。下節課會演示如何監視那些廣播來提高用戶的總體體驗。