Android官方开发文档Training系列课程中文版:管理音频播放之管理音频焦点
原文地址:http://android.xsoftlab.net/training/managing-audio/audio-focus.html
因為可能會存在多個APP播放音頻,所以考慮它們之間的交互方式是一件很重要的事情。為了避免多個音樂播放器APP在同一時間播放音樂,Android使用了音頻焦點的方式來管理音頻的播放,只有獲取了音頻焦點的APP才可以播放音頻。
在APP開始播放音頻之前,APP需要請求以及接收音頻的焦點。同樣的,APP還應該知道如何監聽音頻焦點的丟失事件,以及當事件發生的時候,如何恰當的作出響應。
請求音頻焦點
在APP播放音頻之前,APP應該對使用的音頻流持有音頻焦點。可以使用 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.registerMediaButtonEventReceiver(RemoteControlReceiver);// Start playback. }一旦APP結束了播放,應該確保調用了abandonAudioFocus()方法。這會通知到系統你不再需要請求焦點,以及它會解注與之關聯的AudioManager.OnAudioFocusChangeListener回調接口。在丟棄短暫焦點的例子中,它允許任何被中止的APP可以繼續播放音頻。
// Abandon audio focus when playback complete am.abandonAudioFocus(afChangeListener);當請求短暫的音頻焦點時,有一些附加選項:無論你是否想要正常開啟”ducking”選項,當一個友好的APP失去音頻焦點的時候,它會立即停止播放。通過請求一個瞬態音頻焦點時,它允許閃避,當你告訴其它音頻APP它可以接收它們的持續播放,只要它們會降低音量直到音頻焦點返回給它。
// 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. }閃避對間歇性的音頻流APP來說特別適合,比如導航方向的播報信息。
當其它APP如上面描述的那樣請求音頻焦點時,它可以在永久的音頻焦點或者短暫的音頻焦點之間選擇,這兩個焦點會由請求焦點時注冊的監聽回調方法回調回來。
處理音頻焦點的丟失
如果APP可以請求到音頻焦點,那么接下來在其它APP請求焦點的時候,它就可能會失去那個焦點。APP如何響應焦點的丟失,取決于丟失的方式。
音頻焦點改變接口的回調方法onAudioFocusChange()會接收一個參數,這個參數用于描述焦點改變事件。特別的,焦點的丟失事件可能與原先部分請求的焦點類型相對應–永久丟失,短暫丟失以及短暫的限制性閃避。
通常來說,音頻焦點的短暫丟失應該致使APP的音頻流靜音。否則就應該保持相同的狀態。你應該繼續監視音頻焦點的改變,以便當APP恢復焦點的時候從暫停的地方恢復播放。
如果音頻焦點的丟失是永久性的,假設現在有其他APP被用來監聽音頻焦點,這時,APP應該有效的自動終止。在實際情況中,這意味著停止播放,移除媒體按鈕監聽器–這運行一個新的音頻播放器來專門處理這些事件,以及丟棄持有的音頻焦點。在那時,在APP重新播放之前,你會期待有用戶來觸發那個請求。
在下面的代碼中,如果音頻丟失是短暫的,我們會暫停播放或者暫停我們的媒體播放器對象,并會在重新獲得焦點時恢復它們。如果丟失是永久性的,它會解注我們的媒體按鈕事件接收器以及停止對音頻焦點改變的監聽。
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!
Ducking 是降低音頻流輸出音量的過程,這可以使得其他APP的短暫音頻聽起來更輕快更和諧,而不會總是打斷APP的播放過程。
下面的代碼,當我們臨時的失去焦點時,會降低媒體播放器對象的音量,當再一次獲得焦點時,會將音量等級恢復至原來的值。
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}} };音頻焦點的丟失是由大多數重要的廣播影響的,但是不單單只是有它引起的。系統會廣播一系列的意圖來使你留意用戶的聽覺體驗。下節課會演示如何監視音頻焦點來增進用戶的整體體驗。
總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:管理音频播放之管理音频焦点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JavaWeb】前端框架之Bootst
- 下一篇: 【Java】如何理解Java中的异常机制