1. 程式人生 > >android AudioManager類詳解

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

執行完成後,將註釋去掉,然後從新編譯。。。