天天看點

android 固定中間焦點,Android音頻焦點處理方法

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

在Android裝置上,預設可以有多個應用同時播放音頻,但是,這種處理帶來的使用者體驗并不好,為了解決這個問題,Android引入了音頻焦點機制,一次隻能有一個App持有音頻焦點。

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

處理音頻焦點一些規則

以下是官方建議的處理音頻焦點應該遵循的一些規則:

在開始播放之前,調用requestAudioFocus()方法,并檢查傳回值是否是AUDIOFOCUS_REQUEST_GRANTED,若成功擷取,則開始播放。

當App失去音頻焦點時,根據失去的焦點類型,應該暫停播放,或者将音量調低。

當播放結束時,釋放音頻焦點。

如何處理音頻焦點

處理音頻焦點都是通過AudioManager這個類,如下是獲得該類執行個體的方法:

AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

下面介紹音頻焦點處理相關的一些方法(不同的Android版本處理音頻焦點的方式略有差别,以下内容基于Android 4.4)。

requestAudioFocus():用于申請音頻焦點

abandonAudioFocus():用于釋放音頻焦點

AudioManager.OnAudioFocusChangeListener接口,提供了onAudioFocusChange()方法來監聽音頻焦點變化

下面進行詳細介紹。

requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)

參數:

AudioManager.OnAudioFocusChangeListener l

用于監聽音頻焦點變化,進而可以進行适當的操作,例如暫停播放等。

streamType

申請音頻焦點處理的音頻類型,例如,當播放音樂時,可以傳入STREAM_MUSIC;當播放鈴聲時,可以傳入STREAM_RING。表中列出了所有的可選值:

android 固定中間焦點,Android音頻焦點處理方法

streamType可選類型

durationHint

可選值有以下五個:

(1) AUDIOFOCUS_GAIN: 此參數表示希望申請一個永久的音頻焦點,并且希望上一個持有音頻焦點的App停止播放;例如在需要播放音樂時。

(2) AUDIOFOCUS_GAIN_TRANSIENT:表示申請一個短暫的音頻焦點,并且馬上就會被釋放,此時希望上一個持有音頻焦點的App暫停播放。例如播放一個提醒聲音。

(3) AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:效果同AUDIOFOCUS_GAIN_TRANSIENT,隻是希望上一個持有焦點的App減小其播放聲音(但仍可以播放),此時會混音播放。例如導航播報。

(4) AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 表示申請一個短暫的音頻焦點,并且會希望系統不要播放任何突然的聲音(例如通知,提醒等),例如使用者在錄音。

傳回值:

AUDIOFOCUS_REQUEST_GRANTED或者AUDIOFOCUS_REQUEST_FAILED

2. abandonAudioFocus(OnAudioFocusChangeListener l)

參數同上。

傳回值同上。

3. AudioManager.OnAudioFocusChangeListener

當音頻焦點發生變化時,可以在OnAudioFocusChangeListener的onAudioFocusChange(int focusChange)方法中監聽到,下面詳細說明該方法。

onAudioFocusChange(int focusChange)

參數:focusChange可以表明目前音頻焦點發生的是何種變化,需要根據該參數狀态做出正确的響應。

分為獲得和丢失兩種情況:

獲得:AUDIOFOCUS_GAIN

表示獲得音頻焦點,此時應該開始播放

丢失音頻焦點,這時分為以下兩種情況:

短暫的丢失:

如果focusChange的值是AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 或者 AUDIOFOCUS_LOSS_TRANSIENT時,你的App需要降低播放音量 或者暫停播放(但是需要記錄目前的播放狀态,以便後續恢複播放)。

在短暫丢失焦點期間,你的App應該持續關注音頻焦點的變化,當再次獲得焦點時,恢複播放。

永久的丢失

若值為AUDIOFOCUS_LOSS,你的App應該立即停止播放,并且當再次獲得音頻焦點時,也不會恢複播放,隻有當使用者主動播放時,再開始播放。

示例

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

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

}

// 當播放完成時,建議調用abandonAudioFocus()方法來釋放音頻焦點,

// 通知系統目前App不再需要音頻焦點,解除OnAudioFocusChangeListener的注冊。

// Abandon audio focus when playback complete

am.abandonAudioFocus(afChangeListener);

以上