Android音頻焦點處理方法

前兩天在項目上做了對音頻焦點使用方法的一個總結(jié),記錄在下面。


在Android設(shè)備上,默認可以有多個應(yīng)用同時播放音頻,但是,這種處理帶來的用戶體驗并不好,為了解決這個問題,Android引入了音頻焦點機制,一次只能有一個App持有音頻焦點。

一般情況下,當(dāng)一個App失去音頻焦點時,為了有較好的用戶體驗,它應(yīng)該主動暫停播放,從而使新獲得音頻焦點的App可以清晰的播放音頻,避免混音的情況。


處理音頻焦點一些規(guī)則

以下是官方建議的處理音頻焦點應(yīng)該遵循的一些規(guī)則:

  1. 在開始播放之前,調(diào)用requestAudioFocus()方法,并檢查返回值是否是AUDIOFOCUS_REQUEST_GRANTED,若成功獲取,則開始播放。
  2. 當(dāng)App失去音頻焦點時,根據(jù)失去的焦點類型,應(yīng)該暫停播放,或者將音量調(diào)低。
  3. 當(dāng)播放結(jié)束時,釋放音頻焦點。

如何處理音頻焦點

處理音頻焦點都是通過AudioManager這個類,如下是獲得該類實例的方法:
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
下面介紹音頻焦點處理相關(guān)的一些方法(不同的Android版本處理音頻焦點的方式略有差別,以下內(nèi)容基于Android 4.4)。

  • requestAudioFocus():用于申請音頻焦點
  • abandonAudioFocus():用于釋放音頻焦點
  • AudioManager.OnAudioFocusChangeListener接口,提供了onAudioFocusChange()方法來監(jiān)聽音頻焦點變化

下面進行詳細介紹。

  1. requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
    參數(shù):
    • AudioManager.OnAudioFocusChangeListener l
      用于監(jiān)聽音頻焦點變化,從而可以進行適當(dāng)?shù)牟僮?,例如暫停播放等?/li>
    • streamType
      申請音頻焦點處理的音頻類型,例如,當(dāng)播放音樂時,可以傳入STREAM_MUSIC;當(dāng)播放鈴聲時,可以傳入STREAM_RING。表中列出了所有的可選值:


      streamType可選類型
    • durationHint
      可選值有以下五個:
      (1) AUDIOFOCUS_GAIN: 此參數(shù)表示希望申請一個永久的音頻焦點,并且希望上一個持有音頻焦點的App停止播放;例如在需要播放音樂時。
      (2) AUDIOFOCUS_GAIN_TRANSIENT:表示申請一個短暫的音頻焦點,并且馬上就會被釋放,此時希望上一個持有音頻焦點的App暫停播放。例如播放一個提醒聲音。
      (3) AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:效果同AUDIOFOCUS_GAIN_TRANSIENT,只是希望上一個持有焦點的App減小其播放聲音(但仍可以播放),此時會混音播放。例如導(dǎo)航播報。
      (4) AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 表示申請一個短暫的音頻焦點,并且會希望系統(tǒng)不要播放任何突然的聲音(例如通知,提醒等),例如用戶在錄音。
      返回值:
      AUDIOFOCUS_REQUEST_GRANTED或者AUDIOFOCUS_REQUEST_FAILED

2. abandonAudioFocus(OnAudioFocusChangeListener l)
參數(shù)同上。
返回值同上。

3. AudioManager.OnAudioFocusChangeListener
當(dāng)音頻焦點發(fā)生變化時,可以在OnAudioFocusChangeListener的onAudioFocusChange(int focusChange)方法中監(jiān)聽到,下面詳細說明該方法。
onAudioFocusChange(int focusChange)
參數(shù):focusChange可以表明當(dāng)前音頻焦點發(fā)生的是何種變化,需要根據(jù)該參數(shù)狀態(tài)做出正確的響應(yīng)。
分為獲得和丟失兩種情況:

  • 獲得:AUDIOFOCUS_GAIN
    表示獲得音頻焦點,此時應(yīng)該開始播放
  • 丟失音頻焦點,這時分為以下兩種情況:
    • 短暫的丟失:
      如果focusChange的值是AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 或者 AUDIOFOCUS_LOSS_TRANSIENT時,你的App需要降低播放音量 或者暫停播放(但是需要記錄當(dāng)前的播放狀態(tài),以便后續(xù)恢復(fù)播放)。
      在短暫丟失焦點期間,你的App應(yīng)該持續(xù)關(guān)注音頻焦點的變化,當(dāng)再次獲得焦點時,恢復(fù)播放。
    • 永久的丟失
      若值為AUDIOFOCUS_LOSS,你的App應(yīng)該立即停止播放,并且當(dāng)再次獲得音頻焦點時,也不會恢復(fù)播放,只有當(dāng)用戶主動播放時,再開始播放。

示例

下面是一個申請長音頻焦點,播放音樂的例子:

AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);  
AudioManager.OnAudioFocusChangeListener afChangeListener =  
    new AudioManager.OnAudioFocusChangeListener() {  
     public void onAudioFocusChange(int focusChange) {  
       if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {  
        // Permanent loss of audio focus  
         // Pause playback immediately  
         mediaController.getTransportControls().pause();  
         mediaController.getTransportControls().stop();  
       } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {  
         // Pause playback  
       } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {  
         // Lower the volume, keep playing  
       } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {  
         // Your app has been granted audio focus again  
         // Raise volume to normal, restart playback if necessary  
       }  
     }  
   };     
 ...
 ...   
 // 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) {  
     // Start playback  

 } 

 // 當(dāng)播放完成時,建議調(diào)用abandonAudioFocus()方法來釋放音頻焦點,
 // 通知系統(tǒng)當(dāng)前App不再需要音頻焦點,解除OnAudioFocusChangeListener的注冊。  
 // Abandon audio focus when playback complete  
 am.abandonAudioFocus(afChangeListener);

以上

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 因為系統(tǒng)中可能會有多個應(yīng)用程序會播放音頻,所以需要考慮他們之間該如何交互,為了避免多個應(yīng)用程序同時播放音樂,...
    ZebraWei閱讀 3,328評論 0 1
  • Media Playback Android多媒體框架包涵了對播放多種通用媒體的類型的支持,所以你可以很容易的集成...
    VegetableAD閱讀 980評論 0 0
  • 這節(jié)課是 Android 開發(fā)(入門)課程 的第二部分《多屏幕應(yīng)用》的第四節(jié)課,導(dǎo)師依然是 Jessica Lin...
    HsuJin閱讀 520評論 1 9
  • Android 音頻焦點(Audio Focus) 引子 說 Audio Focus 前先說個很簡單需求:來電時暫...
    suym閱讀 3,910評論 0 0
  • 注:解讀只是自己暫時的淺見。 【解讀】 1、老子從五個例子說明,我們做事情是可以達到極致的狀態(tài)。那怎么樣才能夠做到...
    吾宗老孫子閱讀 501評論 1 0

友情鏈接更多精彩內(nèi)容