AudioFocus媒體焦點的獲取:AudioManager


        demo:項目

        官方文檔中文翻譯:https://blog.csdn.net/dearbaba_8520/article/details/81557975

        AudioFocus媒體焦點:

        Android是多任務系統,Audio系統是競爭資源。Android2.2之前,沒有內建的機制來解決多個程序競爭Audio的問題,2.2引入了稱作AudioFocus的機制來管理對Audio資源的競爭的管理與協調。

        按照AudioFocus的機制,在使用AudioStream之前,需要申請AudioFocus,在獲得AudioFocus之后才可以使用相應的AudioStream;如果有別的程序競爭你正在使用的AudioStream,你的程序需要在收到通知之后做停止播放或者降低聲音的處理。值得指出的是,這種機制是需要合作完成的,需要所有使用Audio資源的程序都按照這種機制來做,而如果有程序在它失去AudioFocus的時候仍然在使用Audio,AudioFocus拿它也沒辦法。而這一點對於開放系統的Android來說很致命的:用戶可能安裝沒遵守這種機制的程序,或者版本太老還沒引入這種機制的程序,這最終會導致很差的用戶體驗。

        1、AudioFocus的申請與釋放

             獲取/放棄AudioFocus的方法都在android.media.AudioManager中,獲取AudioFocus用requestAudioFocus();用完之后,放棄AudioFocus,用abandonAudioFocus()

        其中,參數:

  •  streamType播放流類型;
  •  durationHint:是持續性的指示:
    • AUDIOFOCUS_GAIN 指示申請得到的Audio Focus不知道會持續多久,一般是長期占有;
    • AUDIOFOCUS_GAIN_TRANSIENT 指示要申請的AudioFocus是暫時性的,會很快用完釋放的;
    • AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 不但說要申請的AudioFocus是暫時性的,還指示當前正在使用AudioFocus的可以繼續播放,只是要“duck”一下(降低音量)。
  •  AudioManager.OnAudioFocusChangeListener 是申請成功之后監聽AudioFocus使用情況的Listener,后續如果有別的程序要競爭AudioFocus,都是通過這個Listener的onAudioFocusChange()方法來通知這個Audio Focus的使用者的。 

        返回值,可能是:

        2、AudioFocus被搶占與重新獲得

        由上節中知道,申請/釋放AudioFocus時傳入了AudioManager.OnAudioFocusChangeListener這個參數,其onAudioFocusChange()方法是Audio Focus被搶占與再次獲得通知的地方。所以,每個要使用AudioFocus的程序都要小心實現這個函數,保證AudioFocus實現的一致性。

  • AUDIOFOCUS_LOSS:失去了Audio Focus,並將會持續很長的時間。這里因為可能會停掉很長時間,所以不僅僅要停止Audio的播放,最好直接釋放掉Media資源。而因為停止播放Audio的時間會很長,如果程序因為這個原因而失去AudioFocus,最好不要讓它再次自動獲得AudioFocus而繼續播放,不然突然冒出來的聲音會讓用戶感覺莫名其妙,感受很不好。這里直接放棄AudioFocus,當然也不用再偵聽遠程播放控制【如下面代碼的處理】。要再次播放,除非用戶再在界面上點擊開始播放,才重新初始化Media,進行播放。
  • AUDIOFOCUS_LOSS_TRANSIENT:暫時失去Audio Focus,並會很快再次獲得。必須停止Audio的播放,但是因為可能會很快再次獲得AudioFocus,這里可以不釋放Media資源;
  • AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:暫時失去AudioFocus,但是可以繼續播放,不過要在降低音量。

      3、下面是onAudioFocusChange()方法處理的代碼片段:

OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {  
    public void onAudioFocusChange(int focusChange) {  
        if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT  
            // Pause playback   
        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {  
            am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);  
            am.abandonAudioFocus(afChangeListener);  
            // Stop playback   
        } else if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {  
            // Lower the volume   
        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {  
            // Resume playback or Raise it back to normal   
        }  
    }  
};   

 

 

      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM