Android 多個應用之間聲音競爭之Android 系統處理音訊焦點(AudioFocus)
阿新 • • 發佈:2018-12-20
問題發現
最近在專案中發現我們的自己的apk和第三方的媒體apk會出現串音問題。即兩者之間的聲音會重疊在一起。
解決問題
1. 使用多媒體按鍵去控制第三方應用的聲音播放(無效果)
通過觸發媒體的按鈕來操作播放器狀態:KeyEvent.KEYCODE_MEDIA_PAUSE
public static void sendMediaButton(Context context, int keyCode) { AudioManager audioManager= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); //先判斷後臺是否再播放音樂 if (audioManager.isMusicActive()){ KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); context.sendOrderedBroadcast(intent,null); keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode); intent = new Intent(Intent.ACTION_MEDIA_BUTTON); intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent); context.sendOrderedBroadcast(intent,null); } }
不知為什麼,使用後沒有效果。於是就有了以下的方法
2. 使用AudioFocus 音訊焦點(問題得到解決)
AudioFoucs 簡介
Android 開發中免不了需要播放視訊,音訊檔案,但是手機上可能有其他的一些軟體,在後臺播放音訊的時候,這個時候另外的軟體也需要播放音訊,這個時候就會出現倆個音訊同時播放的問題,在 Android2.2 之後提供了 audioFocus獲取音訊的焦點,但是這個並不是強制需要實現的,所以當你在測試的時候,有的應用沒有處理音訊焦點,所以會有和其他應用串音的現象。
個人認為這個 audiofocus 就類似於一個 flag 全域性變數一樣。然後各個應用根據這個值是設定自己的音訊要播放還是暫停。如果獲得了焦點,則可以播放,如果失去了焦點,則應該暫停正在播放的音訊。
AudioFocus 用法
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN)
此處 requestAudioFocus後面第一引數傳null,是直接去請求音訊焦點的動作。當然這裡不建議這樣。這種太暴力。建議null這裡替換成一個listener監聽。然後通過去實現這個listener去監聽焦點的變化,從而去做一些暫停播放音樂的動作。
audioManager.requestAudioFocus(mAudioFocusChange , AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN)
private AudioManager.OnAudioFocusChangeListener mAudioFocusChange = new
AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange){
case AudioManager.AUDIOFOCUS_GAIN:
//當其他應用申請焦點之後又釋放焦點會觸發此回撥
//可重新播放音樂
Log.d(TAG, "AUDIOFOCUS_GAIN");
start();
break;
case AudioManager.AUDIOFOCUS_LOSS:
//長時間丟失焦點,當其他應用申請的焦點為 AUDIOFOCUS_GAIN 時,
//會觸發此回撥事件,例如播放 QQ 音樂,網易雲音樂等
//通常需要暫停音樂播放,若沒有暫停播放就會出現和其他音樂同時輸出聲音
Log.d(TAG, "AUDIOFOCUS_LOSS");
stop();
//釋放焦點,該方法可根據需要來決定是否呼叫
//若焦點釋放掉之後,將不會再自動獲得
mAudioManager.abandonAudioFocus(mAudioFocusChange);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
//短暫性丟失焦點,當其他應用申請 AUDIOFOCUS_GAIN_TRANSIENT 或
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE 時,
//會觸發此回撥事件,例如播放短視訊,撥打電話等。
//通常需要暫停音樂播放
stop();
Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT");
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
//短暫性丟失焦點並作降音處理
Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
break;
}
}
};
使用完後丟點焦點:
audioManager .abandonAudioFocus(mAudioFocusChange )