Android開發(fā)者需要利用不同的接口來(lái)進(jìn)行音頻資源的播放,AudioManager通過(guò)音頻服務(wù),為上層提供了音量和鈴聲模式控制的接口,鈴聲模式控制包括揚(yáng)聲器、耳機(jī)、藍(lán)牙等是否打開,麥克風(fēng)是否靜音等。在開發(fā)多媒體應(yīng)用時(shí)會(huì)經(jīng)常用到AudioManager。
利用AudioManager來(lái)管理音量和鈴聲模式控制,通過(guò)和MediaPlayer、MediaRecorder等協(xié)同即可完成多媒體的播放,AudioManager是與UI層之間交互的接口。AudioManager是AudioService和Audio System的上層封裝。
AudioManager常用的方法如下:
getService() //獲取音頻服務(wù)
isSpeakerphoneOn() //判斷揚(yáng)聲器是否打開
adjustStreamVolume() //調(diào)節(jié)流的音量,需要指定流的類型
setRingerMode() //設(shè)置鈴聲模式,鈴聲模式分正常、靜音、振動(dòng)3種模式
isBluetoothScoOn() //判斷藍(lán)牙SCO是否打開
isBluetoothA2dpOn() //判斷藍(lán)牙A2DP是否打開
isWiredHeadsetOn() //判斷有線耳機(jī)是否打開
isMicrophoneMute() //判斷麥克風(fēng)是否靜音
AudioManager與Audio Service的關(guān)系如下圖所示:
Audio Manager與Audio Service的關(guān)系圖]
為了進(jìn)行音頻的管理,首先需要獲得音頻服務(wù),獲得音頻服務(wù)的方法為:
private static IAudioService getService()
{
if (sService !=null) {
return sService;
}
IBinder b=ServiceManager.getService(Context.AUDIO_SERVICE);
sService=IAudioService.Stub.asInterface(b);
return sService;
}
當(dāng)音頻信息發(fā)生變化時(shí),AudioManager會(huì)廣播特定的Intent給上層,具體策略如下:
當(dāng)音頻輸出設(shè)備發(fā)生變化,如有線耳機(jī)被拔出、A2DP的音頻槽被斷開,或者底層的音頻系統(tǒng)(Audio System)自動(dòng)將音頻切換到揚(yáng)聲器上時(shí),AudioManager會(huì)向上層發(fā)送ACTION_AUDIO_BECOMING_NOISY消息,此時(shí)應(yīng)用應(yīng)采用暫停、降低音量或者其他策略來(lái)減小用戶體驗(yàn)上感受到的噪音。
當(dāng)鈴音模式被改變時(shí),AudioManager會(huì)向上層發(fā)送RINGER_MODE_ CHANGED_ACTION消息。
AudioManager為上層提供的鈴聲包括:靜音(RINGER_MODE_SILENT)、振動(dòng)(RINGER_MODE_VIBRATE)、標(biāo)準(zhǔn)(RINGER_MODE_NORMAL)等模式。
AudioManager為上層提供的音頻類型包括:呼叫(STREAM_VOICE_CALL)、系統(tǒng)音(STREAM_SYSTEM)、電話鈴聲(STREAM_RING)、音樂播放(STREAM_MUSIC)、鬧鐘(STREAM_ALARM)、提示音(STREAM_ NOTIFICATION)、藍(lán)牙接聽電話(STREAM_BLUETOOTH_SCO)、部分如和日本所需的增強(qiáng)型系統(tǒng)音(STREAM_SYSTEM_ENFORCED)、DTMF音(STREAM_DTMF)、TTS音(STREAM_TTS)。這些音頻類型均是AudioManager對(duì)底層音頻系統(tǒng)的封裝。
當(dāng)多個(gè)音頻資源并發(fā)、沖突時(shí),Android支持排他性播放,方法為:AudioManager::setStreamSolo(int streamType, boolean state)和AudioManager:: setStreamMute(int streamType, boolean state)。其中AudioManager::setStreamSolo()表示將其他音頻流靜音,AudioManager::setStreamMute()表示將某一音頻流靜音。
在AudioManager中還定義了與有線耳機(jī)、藍(lán)牙耳機(jī)、麥克風(fēng)的交互和狀態(tài)判斷。以PhoneApp.java為例,當(dāng)收到ACTION_HEADSET_PLUG消息時(shí),PhoneAppBroadcastReceiver會(huì)發(fā)送EVENT_WIRED_HEADSET_PLUG 給處理函數(shù),處理過(guò)程如下:
代碼10-1 PhoneApp對(duì)ACTION_HEADSET_PLUG的處理
case EVENT_WIRED_HEADSET_PLUG:
Phone.State phoneState=phone.getState();
if (phoneState==Phone.State.OFFHOOK) {
if (!isShowingCallScreen() &&
(mBtHandsfree==null||!mBtHandsfree.isAudioOn())) {
if (!isHeadsetPlugged()) {
SpeakerMode(getApplicationContext());
} else {
PhoneUtils.turnOnSpeaker(getApplicationContext(), false, false);
}
}
}
updateProximitySensorMode(phoneState);
if (mTtyEnabled) {
sendMessage(obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
}
break;