您的應用程式在開始播放音頻檔案前,首先應該請求獲得音頻焦點,並且應該同時註冊監聽音頻焦點的丟失通知,即如果音頻焦點被系統或其他的應用程式搶佔時,您的應用程式可以做出合適的響應。
擷取音頻焦點
您的應用程式在開始播放任何音頻之前,首先應該持有流的音頻焦點。
可以通過調用 requestAudioFocus() 來實現,如果請求成功,返回 AUDIOFOCUS_REQUEST_GRANTED 。
您必須指定流類型使用的是哪一個流)和音頻焦點的類型短暫的或是持久的)。
瞬態焦點用來播放很短時間的音頻例如,播放導航指令)。
持久焦點用來播放較長一段時間的音頻例如,播放音樂)。
下面的代碼片斷示範了請求音樂音頻流的永久音頻焦點。
例如當使用者按下播放背景音樂的按鍵,您應該立即請求音頻焦點,當成功獲得了焦點後再開始播放音樂。
- AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
- ...
-
- // Request audio focus for playback
- 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.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
- // Start playback.
- // 開始播放音樂檔案
- }
一旦您的應用程式完成了播放,請記得要調用 abandonAudioFocus() 方法來通知系統釋放音頻焦點,同時登出相關的 AudioManager.OnAudioFocusChangeListener 。這樣當您的應用程式釋放了音頻焦點,則系統會允許其他被中斷的應用程式重新擷取該焦點來繼續播放。
- // Abandon audio focus when playback complete
- am.abandonAudioFocus(afChangeListener);
當請求瞬態音頻焦點時有一個附加參數可供設定,即是否允許 “DUCK”。通常當應用程式失去了音頻焦點時應該停止播放。如果擷取短暫音頻焦點的時候設定了”DUCK” 附加參數,則允許其他的應用程式繼續播放,不需要停止,只要降低音量就可以了,然後直到您的應用程式釋放了焦點,其他應用程式再重新獲得的時候,將音量還 原到有一開始的狀態。
- // 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.
- }
“DUCK” 特別適合那種間歇性播放音頻流的應用程式,如駕駛導航的聲音提示。
每當其他的應用程式請求獲得音頻焦點永久性的,短暫的,短暫並且支援DUCK的)的時候,您應用程式中註冊的音頻焦點監聽器都會收到相應的訊息通知。
處理音頻焦點的丟失
如果您的應用程式可以請求音頻焦點,那麼當其他應用程式申請的時候,您的應用程式也可能會丟失音頻焦點。怎麼樣應對音頻焦點丟失的情況則取決於音頻焦點丟失的方式。
當音頻焦點丟失時,您註冊的監聽函數onAudioFocusChange()會收到一個事件通知,通知中的參數包括了具體的資訊,比如是永久焦點丟失,短暫焦點丟失,還是短暫焦點且允許DUCK的焦點丟失。
通常,如果是短暫焦點的丟失,您的應用程式應該暫停當前的播放,但其他狀態資訊繼續保持,並且應該持續監聽音頻焦點的改變,一旦重新獲得了音頻焦點,則可以馬上恢複到以前的播放狀態。
假如是永久焦點的丟失,則通常意味著其他應用程式要長時間播放音頻了,您的應用程式應該停止播放,放棄音頻焦點的監聽,並登出所有的媒體按鈕監聽 器,從而讓獲得焦點的其他應用程式來監聽媒體播放控制按鈕的按鍵訊息。如果要恢複您應用程式的播放狀態,則通常需要使用者重新啟動您的應用程式。
在下面的程式碼片段中,如果丟失的是短暫音頻焦點,則暫訂當前應用程式的播放,如果丟失的是永久音頻焦點,則停止當前應用程式的播放,停止監聽音頻焦點的變更,並登出媒體按鈕事件的監聽。
- 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
- }
- }
- };
如果丟失的短暫音頻焦點允許DUCK狀態,在這種情況下,應用程式降低音量繼續播放,不需要暫停。
Duck!
DUCK:降低您應用程式的音量,從而不會打擾其他應用程式音訊播放。
在下面的程式碼片段中,當我們失去焦點的時候,降低了媒體播放的音量,重新獲得焦點的時候,將音量恢複到原來的狀態。
- 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
- }
- }
- };
音頻焦點的丟失是非常重要的一種系統狀態變化通知,系統會廣播很多有關音頻狀態變化的通知,您的應用程式應該監聽這些變化,並作出合適的應對方案,從而提高使用者的音樂體驗。
參考文摘:
http://developer.android.com/training/managing-audio/audio-focus.html
原文連結:
http://blog.zhourunsheng.com/2011/12/android-%E9%9F%B3%E4%B9%90%E7%BC%96%E7%A8%8B%E4%B8%93%E9%A2%98%E4%B9%8B%E7%AE%A1%E7%90%86%E9%9F%B3%E9%A2%91%E7%84%A6%E7%82%B9/