Android的framework層是如何對鈴聲的音量進行調整的
android.media.AudioManager中包含了對android.media.AudioService的跨程序AIDL呼叫封裝。因此,調整鈴聲音量是通過AudioManager間接呼叫AudioService.adjustStreamVolume方法完成。
鈴聲音量調整分為兩步:先檢視模式(Ring mode)是否需要調整,如果不需要調整模式,當前模式一定是正常模式(Normal mode),那就需要調整鈴聲音量。
調整模式通過呼叫checkForRingerModeChange(oldIndex, direction);實現,調整音量通過呼叫streamState.adjustIndex(direction)實現。具體程式碼參考/framework/base/media/java/android/media/AudioService.java中的public void adjustStreamVolume(int streamType, int direction, int flags)方法。
該方法先檢查模式是否需要調整,再進行音量調整。調整完畢後,做了兩件事:
1、通過mVolumePanel.postVolumeChanged(streamType, flags);向用戶顯示改變結果。
2、通過sendVolumeUpdate(streamType);廣播音量有改變的系統事件。
改變音量這個功能與使用者介面有關的有兩個部分,分別是/framework/base/core/java/android/view/VolumePanel.java和/framework/base/services/java/com/android/server/status/StatusBarPolicy.java。
VolumePanel主要負責向用戶顯示一個Toast,告訴使用者目前的模式(Ring Mode)和音量大小。每次AudioService通過向post一系列Message給VolumePanel,來驅動Toast的顯示。
StatusBarPolicy主要負責在靜音模式(silent mode)和振動模式(vibrate mode)下在狀態列(status bar)的右方顯示一個代表相應意義的圖示。
系統啟動後,StatusBarPolicy會註冊一個Receiver,它可以接收很多種廣播,其中就有AudioService在完成每一次的模式和音量更新時發出的兩個廣播事件AudioManager.RINGER_MODE_CHANGED_ACTION和AudioManager.VIBRATE_SETTING_CHANGED_ACTION。
接收到這兩個事件時,StatusBarPolicy就會呼叫updateVolume()來更新狀態列上的圖示。