1. 程式人生 > >Android中的Audio播放:控制Audio輸出通道切換

Android中的Audio播放:控制Audio輸出通道切換

2012-04-03

Audio 輸出通道有很多,Speaker、headset、bluetooth A2DP等。通話或播放音樂等使用Audio輸出過程中,可能發生Audio輸出通道的切換。比如,插入有線耳機播放音樂時,聲音是從耳機發出的;而此時拔出耳機,Audio輸出通道會發生切換。如果音樂播放器不做處理,Audio輸出是被切換到揚聲器的,聲音直接從Speaker發出。我們在編寫程式時,要捕獲並按照需求來處理這樣的事,本文就是講解如何處理的。

Android中可以通過android.media.AudioManager查詢當前Audio輸出的情況,並且在Audio輸出發生變化時,捕獲並處理這種變化。

AudioNoisy AudioManager

一、Audio輸出狀態查詢與控制

android.media.AudioManager提供的下列方法可以用來查詢當前Audio輸出的狀態:

  •  isBluetoothA2dpOn():檢查A2DPAudio是否通過藍芽耳機;
  •  isSpeakerphoneOn():檢查揚聲器是否開啟;
  •  isWiredHeadsetOn():檢查線控耳機是否連著;注意這個方法只是用來判斷耳機是否是插入狀態,並不能用它的結果來判定當前的Audio是通過耳機輸出的,這還依賴於其他條件。

另外還有一些設定這些Audio輸出的setXYZ()方法,這些方法在一般使用Audio輸出的應用程式不要直接呼叫,他們由系統來管理,實現Audio輸出通道的自動切換。除非,介面提供給使用者切換的選單或按鈕,而使用者選擇了卻換,比如要直接選擇揚聲器發聲,可直接呼叫setSpeakerphoneOn()。

二、Audio輸出通道切換的事件的捕獲與處理

因為耳機插拔、藍芽耳機的斷開,Audio輸出通路會自動切換。此時正在播放Audio的程式要獲得通知,知道這一事件的發生。Android中是通過廣播ACTION_AUDIO_BECOMING_NOISY這個Intent通知的。

處理廣播的較好的方式,是動態註冊/登出自己所關心的廣播。下面程式碼演示了,開始播放時註冊廣播的Receiver;停止播放時登出廣播的Receiver。對Audio輸出通道切換的處理是暫停當前的播放,不直接從新的通道里發出聲來。

private class NoisyAudioStreamReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
            // Pause the playback
        }
    }
}

private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);

private void startPlayback() {
    registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);
}

private void stopPlayback() {
    unregisterReceiver(myNoisyAudioStreamReceiver);
}

三、Audio輸出通道切換的典型場景—— 用耳機聽音樂時,拔出耳機

聽耳機聽音樂時,耳機別拔出的時序圖如下:

AudioNoisy_Sequence.jpg

圖中:

  •  AudioNoisy Client註冊了偵聽廣播AudioManager.ACTION_AUDIO_BECOMING_NOISY[Step#1 ~ #2];
  •  用耳機一直在聽音樂;
  •  HeadsetObserver一直在監視耳機狀態的變化。檢測到耳機被拔出之後,發出廣播AudioManager.ACTION_AUDIO_BECOMING_NOISY[Step#3~4];
  •  AudioNoisy Client收到了廣播,傳送暫停命令給MediaPaybackService去暫停當前的播放 [Step#5~6]。

小結

        Audio 輸出通道切換時,要根據具體需求來做相應的處理。