Android中的Audio播放:音量和遠程播放控制
本文從Audio控制使用的角度,講解了AudioStream的分類,硬件音量控制鍵調整對相應AudioStream音量大小的影響,以及如何響應遠程MediaButton控制Audio播放。
1. Audio Stream
Android為不同的應用場合定義了不同的Audio Stream: Voice Call, Ring, Music,Alarm, Notification, DTMF。 這些AudioStream是相互獨立的,所以也有各自的音量。AudioStream的定義在android.media.AudioManager 中,如下圖所示:

2. 硬件音量控制鍵Vol+/-控制Audio Stream的音量
用戶按下音量控制的HardKey,希望能調出音量調整的界面。
缺省情況下,按下音量控制的硬件控制鍵Vol+/-,調節的是當前被激活的(Active)AudioStream的音量,如果你的程序當前沒有正在播放任何聲音,按下Vol+/-調節的是來電鈴聲的音量。【筆者注:基本是翻譯的原話,需要明確!By default, pressing the volume controls modifythe volume of the active audio stream. If your app isn't currently playing anything, hitting the volume keys adjusts the ringer volume.】

在 某一個程序運行時,希望按下Vol+/-調節的是當前所使用的AudioStream的音量,Android在Activity中提供了 setVolumeControlStream()方法用來指定你的應用程序使用的Audio Stream類型。所以,如果你的程序用到Audio的播放,你首先要知道你的程序所用的Audio Stream類型,并在onCreate()中調用setVolumeControlStream()來設定Audio Stream的類型。
Q:setVolumeControlStream()之后就起效,還是可見之后才有用?后臺播放呢?
要明確這些標紅的地方,需要看Android的內部實現!//TODO:明確化;內部實現,另外專題寫…
3. 遙控Audio Playback
有些耳機上有諸如音量控制、切換前一首下一首歌、播放/暫停等控制鍵,記得Bluetooth也有個Profile是能遠程控制的。這些鍵被按下后,Android是通過broadcast ACTION_MEDIA_BUTTON廣播出去的。
所以,要在你的應用中處理這些按鍵,只要偵聽這個廣播,并處理即可。
如果知道什么時候開始偵聽廣播,程序中動態注冊/注銷偵聽都是很好的選擇(與,寫在AndroidManifest中,apk加載時就注冊相比)。而Audio控制在什么時候才處理這些鍵值是比較明確的,一般獲得AudioFocus的情況下,響應ACTION_MEDIA_BUTTON廣播;失去Audio Focus的情況下,不響應ACTION_MEDIA_BUTTON廣播,這也就是相應registerMediaButtonEventReceiver()/unregisterMediaButtonEventReceiver()的最佳時機。
ACTION_MEDIA_BUTTON廣播的處理,只要在override onReceive(),并在其中通過判斷是否Intent.ACTION_MEDIA_BUTTON確保是這個廣播,從Intent.EXTA_KEY_EVENT中獲得KeyEvent,做相應的處理即可。
涉及的幾個類的關系圖如下:

相應處理的代碼片段如下:
public class RemoteControlReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (KeyEvent.KEYCODE_MEDIA_PLAY == event.getKeyCode()) {
// Handle key press.
}
}
}
}
總結一下要點:
1. Android的Audio控制是按照Audio Stream劃分的;
2. 各 個Audio Stream的音量是獨立的。推薦在onCreate()中通過Activity.setVolumeControlStream()方法設置所使用 AudioStream的類型,實現按下硬鍵Vol+/-調整的是相對應AudioStream的音量;
3. 偵聽Intent.ACTION_MEDIA_BUTTON廣播實現對遠程Media控制的處理。
主要參考資源:
1. Controllingyour app’s volume and playback
2. Android Reference API.