android AudioManager類詳解
首先上層Java呼叫
XXXPlayer
AudioManager audiomanage = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audiomanager就是我們定義的控制系統聲音的物件,(如果context報錯,可將其改成XXXPlayer.this)
audiomanager.SetStreamVolume(AA,BB,CC),是我們可以直接使用的AudioManager的成員函式,3個引數表示的意思:AA:有內建的常量,可以在AudioManager裡面查到相關的定義,我們在此用 AudioManager.STREAM_MUSIC, BB:自己設定音量的值,CC:也是一些標示量,我在此設定為0;
1.AudioManager.java
public void setStreamVolume(int streamType, int index, int flags);上層介面
1)呼叫IAudioService service = getService(); 當程式開啟時會獲得service,呼叫此來獲得
2.執行ServiceManager.java
public static IBinder getService(String name)獲取audio服務
3.AudioService.java
public void setStreamVolume(int streamType, int index, int flags)//服務介面
1) private void setStreamVolumeInt(int streamType, int index, boolean force, boolean lastAudible)//服務函式
2)呼叫以下函式
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, streamType, SENDMSG_NOOP, 0, 0,streamState, 0)
//Post message to set system volume (it in turn will post a message
// to persist)
3)AudioHandler::setSystemVolume(VolumeStreamState streamState);//sendmsg(...)後執行函式
4)呼叫AudioHandler::setStreamVolumeIndex(int stream, int index)
5)AudioSystem.setStreamVolumeIndex(stream,index);//audioSystem介面
static int android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
1)呼叫AudioSystem::setStreamVolumeIndex
6.status_t AudioSystem::setStreamVolumeIndex(stream_type stream, int index)(處理到這時,也可以直接走AudioFlinger路線,不經過策略)
1)獲得服務 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
2)呼叫aps->setStreamVolumeIndex(stream, index)
7.status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
1)呼叫mpPolicyManager->setStreamVolumeIndex(stream, index)
status_t AudioPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
1)記錄音量index: mStreams[stream].mIndexCur = index
2)compute and apply stream volume on all outputs:
checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device())
8.status_t AudioPolicyManager::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
1)計算音量:float volume = computeVolume(stream, index, output, device);
2)呼叫:mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
9.status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
呼叫mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
10.status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
呼叫insertCommand_l(command, delayMs);
補充1)在條用getService();獲取服務的時候 ,實際呼叫的是ServiceManager.getService(context);
系統服務都是由serviceManager來管理的,要新增服務,可以呼叫serviceManager.AddService(context,service);
每新增一個service,都會有對應的唯一context, 當getService的時候就會根據context獲得相應的服務,
可檢視ServiceManager.java, ServiceManager.h/cpp
補充2) AudioService 的介面在 IaudioService.aidl中定義。新增自定義功能時( 我們建立控制介面比如建立個音效處理的介面SetEffectVolume(XXX),可以參照SetStreamVolume(a,b,c))別忘了修改此處,否則,AudioManager 會出現cannot find symbol..錯誤!!!
補充3)編譯的時候可能會在Audiomanager.java中呼叫自己寫的介面時出錯,此時先將該檔案中的呼叫註釋掉,執行 make update-api
執行完成後,將註釋去掉,然後從新編譯。。。