Android 4.4音量键控制音量流程

1、在AudioManager.java中的handleKeyDown函数中接收音量键的按键消息

  1. public void handleKeyDown(KeyEvent event, int stream) {
  2. int keyCode = event.getKeyCode();
  3. switch (keyCode) {
  4. case KeyEvent.KEYCODE_VOLUME_UP:
  5. case KeyEvent.KEYCODE_VOLUME_DOWN:
  6. /*
  7. * Adjust the volume in on key down since it is more
  8. * responsive to the user.
  9. */
  10. int flags = FLAG_SHOW_UI | FLAG_VIBRATE;
  11. if (mUseMasterVolume) {
  12. adjustMasterVolume(
  13. keyCode == KeyEvent.KEYCODE_VOLUME_UP
  14. ? ADJUST_RAISE
  15. : ADJUST_LOWER,
  16. flags);
  17. } else {
  18. adjustSuggestedStreamVolume(
  19. keyCode == KeyEvent.KEYCODE_VOLUME_UP
  20. ? ADJUST_RAISE
  21. : ADJUST_LOWER,
  22. stream,
  23. flags);
  24. }
  25. break;
  26. case KeyEvent.KEYCODE_VOLUME_MUTE:
  27. if (event.getRepeatCount() == 0) {
  28. if (mUseMasterVolume) {
  29. setMasterMute(!isMasterMute());
  30. } else {
  31. // TODO: Actually handle MUTE.
  32. }
  33. }
  34. break;
  35. }
  36. }

2、根据音量键调节走else分支,进入adjustSuggestedStreamVolume函数中

  1. public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
  2. IAudioService service = getService();
  3. Log.d(TAG, "adjustSuggestedStreamVolume: Direction = " + direction
  4. + ", streamType = " + suggestedStreamType);
  5. try {
  6. if (mUseMasterVolume) {
  7. service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
  8. } else {
  9. service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags,
  10. mContext.getOpPackageName());
  11. }
  12. } catch (RemoteException e) {
  13. Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e);
  14. }
  15. }

3、进入AudioService.java中的adjustSuggestedStreamVolume函数中

  1. public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
  2. String callingPackage) {
  3. if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream="+suggestedStreamType+" direction ="+direction+" flags="+flags);
  4. int streamType;
  5. Log.d(TAG, "adjustSuggestedStreamVolume() mVolumeControlStream="+mVolumeControlStream);
  6. if (mVolumeControlStream != -1) {
  7. streamType = mVolumeControlStream;
  8. Log.d(TAG, "adjustSuggestedStreamVolume() getMode()="+getMode());
  9. Log.d(TAG, "adjustSuggestedStreamVolume() AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) ="+AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));
  10. Log.d(TAG, "adjustSuggestedStreamVolume() AudioSystem.isStreamActive(AudioSystem.STREAM_VOICE_CALL, 0) ="+AudioSystem.isStreamActive(AudioSystem.STREAM_VOICE_CALL, 0));
  11. } else {
  12. streamType = getActiveStreamType(suggestedStreamType);
  13. }
  14. Log.d(TAG, "adjustSuggestedStreamVolume() streamType2="+streamType);
  15. // Play sounds on STREAM_RING only and if lock screen is not on.
  16. if ((streamType != STREAM_REMOTE_MUSIC) &&
  17. (flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
  18. ((mStreamVolumeAlias[streamType] != AudioSystem.STREAM_RING)
  19. || (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {
  20. flags &= ~AudioManager.FLAG_PLAY_SOUND;
  21. }
  22. if (streamType == STREAM_REMOTE_MUSIC) {
  23. // don‘t play sounds for remote
  24. flags &= ~(AudioManager.FLAG_PLAY_SOUND|AudioManager.FLAG_FIXED_VOLUME);
  25. //if (DEBUG_VOL) Log.i(TAG, "Need to adjust remote volume: calling adjustRemoteVolume()");
  26. mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, flags);
  27. } else {
  28. adjustStreamVolume(streamType, direction, flags, callingPackage);
  29. }
  30. }

4、进入adjustStreamVolume函数中

  1. /** @see AudioManager#adjustStreamVolume(int, int, int) */
  2. public void adjustStreamVolume(int streamType, int direction, int flags,
  3. String callingPackage) {
  4. if (mUseFixedVolume) {
  5. return;
  6. }
  7. if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream="+streamType+", dir="+direction);
  8. ensureValidDirection(direction);
  9. ensureValidStreamType(streamType);
  10. Log.v(TAG,"adjustStreamVolume streamType1 : "+streamType);
  11. // use stream type alias here so that streams with same alias have the same behavior,
  12. // including with regard to silent mode control (e.g the use of STREAM_RING below and in
  13. // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
  14. int streamTypeAlias = mStreamVolumeAlias[streamType];
  15. VolumeStreamState streamState = mStreamStates[streamTypeAlias];
  16. final int device = getDeviceForStream(streamTypeAlias);
  17. Log.v(TAG,"adjustStreamVolume streamTypeAlias : "+streamTypeAlias+" device:"+device);
  18. int aliasIndex = streamState.getIndex(device);
  19. boolean adjustVolume = true;
  20. int step;
  21. // skip a2dp absolute volume control request when the device
  22. // is not an a2dp device
  23. if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 &&
  24. (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
  25. return;
  26. }
  27. if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),
  28. callingPackage) != AppOpsManager.MODE_ALLOWED) {
  29. return;
  30. }
  31. // reset any pending volume command
  32. synchronized (mSafeMediaVolumeState) {
  33. mPendingVolumeCommand = null;
  34. }
  35. flags &= ~AudioManager.FLAG_FIXED_VOLUME;
  36. if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
  37. ((device & mFixedVolumeDevices) != 0)) {
  38. flags |= AudioManager.FLAG_FIXED_VOLUME;
  39. // Always toggle between max safe volume and 0 for fixed volume devices where safe
  40. // volume is enforced, and max and 0 for the others.
  41. // This is simulated by stepping by the full allowed volume range
  42. if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
  43. (device & mSafeMediaVolumeDevices) != 0) {
  44. step = mSafeMediaVolumeIndex;
  45. } else {
  46. step = streamState.getMaxIndex();
  47. }
  48. if (aliasIndex != 0) {
  49. aliasIndex = step;
  50. }
  51. } else {
  52. // convert one UI step (+/-1) into a number of internal units on the stream alias
  53. step = rescaleIndex(10, streamType, streamTypeAlias);
  54. }
  55. // If either the client forces allowing ringer modes for this adjustment,
  56. // or the stream type is one that is affected by ringer modes
  57. if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
  58. (streamTypeAlias == getMasterStreamType())) {
  59. int ringerMode = getRingerMode();
  60. // do not vibrate if already in vibrate mode
  61. if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
  62. flags &= ~AudioManager.FLAG_VIBRATE;
  63. }
  64. // Check if the ringer mode changes with this volume adjustment. If
  65. // it does, it will handle adjusting the volume, so we won‘t below
  66. adjustVolume = checkForRingerModeChange(aliasIndex, direction, step);
  67. }
  68. int oldIndex = mStreamStates[streamType].getIndex(device);
  69. if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
  70. // Check if volume update should be send to AVRCP
  71. if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
  72. (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
  73. (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
  74. synchronized (mA2dpAvrcpLock) {
  75. if (mA2dp != null && mAvrcpAbsVolSupported) {
  76. mA2dp.adjustAvrcpAbsoluteVolume(direction);
  77. }
  78. }
  79. }
  80. if ((direction == AudioManager.ADJUST_RAISE) &&
  81. !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
  82. Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);
  83. mVolumePanel.postDisplaySafeVolumeWarning(flags);
  84. } else if (streamState.adjustIndex(direction * step, device)) {
  85. // Post message to set system volume (it in turn will post a message
  86. // to persist). Do not change volume if stream is muted.
  87. sendMsg(mAudioHandler,
  88. MSG_SET_DEVICE_VOLUME,
  89. SENDMSG_QUEUE,
  90. device,
  91. 0,
  92. streamState,
  93. 0);
  94. }
  95. }
  96. int index = mStreamStates[streamType].getIndex(device);
  97. sendVolumeUpdate(streamType, oldIndex, index, flags);
  98. }

在sendMsg发送Message进入handler中处理,调用setDeviceVolume函数

  1. private void setDeviceVolume(VolumeStreamState streamState, int device) {
  2. // Apply volume
  3. streamState.applyDeviceVolume(device);
  4. // Apply change to all streams using this one as alias
  5. int numStreamTypes = AudioSystem.getNumStreamTypes();
  6. for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
  7. if (streamType != streamState.mStreamType &&
  8. mStreamVolumeAlias[streamType] == streamState.mStreamType) {
  9. // Make sure volume is also maxed out on A2DP device for aliased stream
  10. // that may have a different device selected
  11. int streamDevice = getDeviceForStream(streamType);
  12. if ((device != streamDevice) && mAvrcpAbsVolSupported &&
  13. ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
  14. mStreamStates[streamType].applyDeviceVolume(device);
  15. }
  16. mStreamStates[streamType].applyDeviceVolume(streamDevice);
  17. }
  18. }
  19. // Post a persist volume msg
  20. sendMsg(mAudioHandler,
  21. MSG_PERSIST_VOLUME,
  22. SENDMSG_QUEUE,
  23. device,
  24. 0,
  25. streamState,
  26. PERSIST_DELAY);
  27. }

调用applyDeviceVolume函数

  1. public void applyDeviceVolume(int device) {
  2. int index;
  3. if (isMuted()) {
  4. index = 0;
  5. } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
  6. mAvrcpAbsVolSupported) {
  7. index = (mIndexMax + 5)/10;
  8. } else {
  9. index = (getIndex(device) + 5)/10;
  10. }
  11. Log.d(TAG,"applyDeviceVolume index:"+index + " mStreamType:" + mStreamType + ",device:" + device);
  12. AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
  13. }

5、调用AudioSystem.java中的setStreamVolumeIndex函数

  1. public static native int setStreamVolumeIndex(int stream, int index, int device);

6、调用AudioSystem.cpp函数中的setStreamVolumeIndex

  1. status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,
  2. int index,
  3. audio_devices_t device)
  4. {
  5. const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
  6. if (aps == 0) return PERMISSION_DENIED;
  7. return aps->setStreamVolumeIndex(stream, index, device);
  8. }

7、调用AudioPolicyService.cpp中的setStreamVolumeIndex

  1. status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
  2. int index,
  3. audio_devices_t device)
  4. {
  5. ALOGD("AudioPolicyService::setStreamVolumeIndex");
  6. if (mpAudioPolicy == NULL) {
  7. return NO_INIT;
  8. }
  9. if (!settingsAllowed()) {
  10. return PERMISSION_DENIED;
  11. }
  12. if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
  13. return BAD_VALUE;
  14. }
  15. Mutex::Autolock _l(mLock);
  16. if (mpAudioPolicy->set_stream_volume_index_for_device) {
  17. ALOGD("mpAudioPolicy->set_stream_volume_index_for_device");
  18. return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
  19. stream,
  20. index,
  21. device);
  22. } else {
  23. ALOGD("mpAudioPolicy->set_stream_volume_index");
  24. return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
  25. }
  26. }

8、调用AudioMTKPolicyManager.cpp中的setStreamVolumeIndex函数

  1. status_t AudioMTKPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream,
  2. int index,
  3. audio_devices_t device)
  4. {
  5. ALOGD("AudioMTKPolicyManager setStreamVolumeIndex stream = %d index = %d device = 0x%x",stream,index,device);
  6. if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
  7. return BAD_VALUE;
  8. }
  9. if (!audio_is_output_device(device)) {
  10. return BAD_VALUE;
  11. }
  12. // Force max volume if stream cannot be muted
  13. if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
  14. ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
  15. stream, device, index);
  16. // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
  17. // clear all device specific values
  18. if (device == AUDIO_DEVICE_OUT_DEFAULT) {
  19. mStreams[stream].mIndexCur.clear();
  20. }
  21. mStreams[stream].mIndexCur.add(device, index);
  22. #ifdef MTK_AUDIO
  23. #ifdef MTK_AUDIO_GAIN_TABLE
  24. mAudioUCM->setStreamVolIndex(stream,index,device);
  25. #endif
  26. #endif
  27. // compute and apply stream volume on all outputs according to connected device
  28. status_t status = NO_ERROR;
  29. for (size_t i = 0; i < mOutputs.size(); i++) {
  30. audio_devices_t curDevice =
  31. getDeviceForVolume(mOutputs.valueAt(i)->device());
  32. if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
  33. #ifdef MTK_AUDIO
  34. status_t volStatus;
  35. // alps00053099 adjust matv volume when record sound stoping, matv sound will out through speaker.
  36. // delay -1 to put this volume command at the end of command queue in audiopolicy service
  37. if(stream ==AudioSystem::MATV &&(mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET ||mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))
  38. {
  39. volStatus =checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice,-1);
  40. }
  41. else
  42. {
  43. volStatus =checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
  44. }
  45. #else
  46. status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
  47. #endif
  48. if (volStatus != NO_ERROR) {
  49. status = volStatus;
  50. }
  51. }
  52. }
  53. return status;
  54. }

9、真正设置是在checkAndSetVolume函数中执行

  1. status_t AudioMTKPolicyManager::checkAndSetVolume(int stream,
  2. int index,
  3. audio_io_handle_t output,
  4. audio_devices_t device,
  5. int delayMs,
  6. bool force)
  7. {
  8. ALOGD(" checkAndSetVolume stream = %d index = %d output = %d device = 0x%x delayMs = %d force = %d"
  9. ,stream,index,output,device,delayMs,force);
  10. // do not change actual stream volume if the stream is muted
  11. if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
  12. ALOGVV("checkAndSetVolume() stream %d muted count %d",
  13. stream, mOutputs.valueFor(output)->mMuteCount[stream]);
  14. return NO_ERROR;
  15. }
  16. // do not change in call volume if bluetooth is connected and vice versa
  17. if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
  18. (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
  19. ALOGD("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
  20. stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
  21. return INVALID_OPERATION;
  22. }
  23. float volume = computeVolume(stream, index, output, device);
  24. ALOGD("checkAndSetVolume volume = %f stream=%d device=%d",volume,stream,device);
  25. #ifdef MTK_AUDIO
  26. #ifdef MTK_AUDIO_GAIN_TABLE
  27. updateAnalogVolume(output,device,delayMs);
  28. #endif
  29. #endif
  30. #ifdef MTK_AUDIO
  31. //for VT notify tone when incoming call. it‘s volume will be adusted in hardware.
  32. if((stream == AudioSystem::VOICE_CALL ||stream == AudioSystem::BLUETOOTH_SCO) && mOutputs.valueFor(output)->mRefCount[stream]!=0 && mPhoneState==AudioSystem::MODE_IN_CALL)
  33. {
  34. volume =1.0;
  35. }
  36. // ALPS00554824 KH: If notifiaction is exist, FM should be mute
  37. if ((stream == AudioSystem::FM) &&
  38. (mOutputs.valueFor(output)->mRefCount[AudioSystem::NOTIFICATION]
  39. || mOutputs.valueFor(output)->mRefCount[AudioSystem::RING]
  40. || mOutputs.valueFor(output)->mRefCount[AudioSystem::ALARM]))
  41. {
  42. volume =0.0;
  43. }
  44. // ALPS001125976 Mute music at ringtone from BT to primary
  45. //if ( (stream == AudioSystem::MUSIC) && (mPhoneState ==AudioSystem::MODE_RINGTONE) && (mStreams[AudioSystem::RING].getVolumeIndex(device)!=mStreams[AudioSystem::RING].mIndexMin) ) {
  46. // volume =0.0;
  47. //}
  48. #endif
  49. //ALOGD("checkAndSetVolume newvolume %f, oldvolume %f,output %d",volume,mOutputs.valueFor(output)->mCurVolume[stream],output);
  50. // We actually change the volume if:
  51. // - the float value returned by computeVolume() changed
  52. // - the force flag is set
  53. if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
  54. force
  55. #ifdef MTK_AUDIO
  56. ||(stream==AudioSystem::FM && output==mPrimaryOutput && (device == AUDIO_DEVICE_OUT_WIRED_HEADSET ||device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE) )//WFD output can‘t affect HwGain,however affect mFmVolume . But PrimaryOutput will use mFmVolume setting
  57. #endif
  58. ) {
  59. #ifdef MTK_AUDIO
  60. int bSetStreamVolume=1;
  61. //Overall, Don‘t set volume to affect direct mode volume setting if the later routing is still direct mode . HoChi . This is very tricky that WFD support FM,others(BT/...) don‘t.
  62. #ifdef MATV_AUDIO_SUPPORT
  63. if( matv_use_analog_input == true){
  64. if((stream==AudioSystem::MATV)&&(output!=mPrimaryOutput||device==AUDIO_DEVICE_NONE)&&device!=AUDIO_DEVICE_OUT_REMOTE_SUBMIX){
  65. bSetStreamVolume=0; //MATV with line-in path is only ouput from primaryoutput
  66. }
  67. }
  68. #endif
  69. //Add device==AUDIO_DEVICE_NONE for ALPS
  70. if((stream==AudioSystem::FM)&&(output!=mPrimaryOutput||device==AUDIO_DEVICE_NONE)&&device!=AUDIO_DEVICE_OUT_REMOTE_SUBMIX){
  71. bSetStreamVolume=0; //FM with line-in path is only ouput from primaryoutput
  72. }
  73. if(bSetStreamVolume==1)
  74. {
  75. #endif
  76. mOutputs.valueFor(output)->mCurVolume[stream] = volume;
  77. ALOGD("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
  78. // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
  79. // enabled
  80. if (stream == AudioSystem::BLUETOOTH_SCO) {
  81. mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);
  82. }
  83. mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
  84. #ifdef MTK_AUDIO
  85. }
  86. else
  87. {
  88. ALOGD("skip setStreamVolume for output %d stream %d, volume %f, delay %d",output, stream, volume, delayMs);
  89. }
  90. #endif
  91. }
  92. ALOGD("checkAndSetVolume() for output %d stream %d, volume %f, delay %d, loc 2", output, stream, volume, delayMs);
  93. if (stream == AudioSystem::VOICE_CALL ||
  94. stream == AudioSystem::BLUETOOTH_SCO) {
  95. float voiceVolume;
  96. // Force voice volume to max for bluetooth SCO as volume is managed by the headset
  97. if (stream == AudioSystem::VOICE_CALL) {
  98. #ifdef MTK_AUDIO
  99. #ifndef MTK_AUDIO_GAIN_TABLE
  100. voiceVolume = computeCustomVoiceVolume(stream, index, output, device);
  101. #endif
  102. #else
  103. voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
  104. #endif
  105. } else {
  106. voiceVolume = 1.0;
  107. }
  108. ALOGD("checkAndSetVolume() voiceVolume %f mLastVoiceVolume %f mPrimaryOutput %d output %d",voiceVolume, mLastVoiceVolume,mPrimaryOutput,output);
  109. if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
  110. mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
  111. #ifdef MTK_AUDIO
  112. #ifdef EVDO_DT_SUPPORT
  113. ALOGD("SetVoiceVolumeIndex=%d %f,%f,%d", index, voiceVolume, mLastVoiceVolume, output == mPrimaryOutput);
  114. //set Volume Index ( for external modem)
  115. AudioParameter param = AudioParameter();
  116. param.addInt(String8("SetVoiceVolumeIndex"), index);
  117. mpClientInterface->setParameters (0 , param.toString(), 0);
  118. #endif
  119. #endif
  120. mLastVoiceVolume = voiceVolume;
  121. }
  122. }
  123. return NO_ERROR;
  124. }
  1. if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
  2. mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
  3. #ifdef MTK_AUDIO
  4. #ifdef EVDO_DT_SUPPORT
  5. ALOGD("SetVoiceVolumeIndex=%d %f,%f,%d", index, voiceVolume, mLastVoiceVolume, output == mPrimaryOutput);
  6. //set Volume Index ( for external modem)
  7. AudioParameter param = AudioParameter();
  8. param.addInt(String8("SetVoiceVolumeIndex"), index);
  9. mpClientInterface->setParameters (0 , param.toString(), 0);
  10. #endif
  11. #endif
  12. mLastVoiceVolume = voiceVolume;
  13. }

函数中经过判断本次音量与上次音量的比较 以及输出设备的比较正确的话,设置到底层

其中之前音量的设置会经过多次的计算,与音频参数等的计算

来自为知笔记(Wiz)

时间: 2024-10-19 01:23:24

Android 4.4音量键控制音量流程的相关文章

Android 长按电源键关机整个流程小学习

最近研究了一下android关机跟重新启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程. 首先还是来看看这个长按电源键都干了些什么吧?一般来说,电源键都是接到PMU上的,PMU来判断是长按还短按,当有按键消息产生的时候,系统会有中断,然后去读PMU的状态就可以知道是什么了.笔者以全志平台的AXP209小议一下,先贴上关键代码: static int axp_battery_event(struct notifier_block *nb, unsigned long eve

手机影音第十天,控制屏幕上下滑动改变音量变化,监听物理键改变音量

代码已托管至码云上,有兴趣的小伙伴可以下载看看,IDE是Android studio 2.3.2 https://git.oschina.net/joy_yuan/MobilePlayer 常见的手机播放器,都有屏幕上下滑动改变音量大小的功能,在此也实现下: 原理是: 1.从手指触碰屏幕,到离开屏幕,计算滑动的高度差,然后拿这个高度差与屏幕的高对比,最后结合总音量,得到改变的音量,具体的公式如下 : 改变的音量=(滑动距离差/屏幕总高度)*总音量 结束滑动后的音量=触碰屏幕时的音量+改变的音量

Android 音量键的监听

实践后的结论: 下面两种都可以获取到音量键的东西,  测试的时候,发现 KeyEvent.KEYCODE_VOLUME_UP 一直按住的时候, 三星的一款平板计数到200,就不在触发该事件; 所以改为 KeyEvent.ACTION_DOWN 时启动一个方法用来计数, KeyEvent.ACTION_UP的停止技数; package com.akm.testvolume; import android.app.Activity; import android.os.Bundle; import

Android 自定义SeekBar动态改变 硬件音量大小 实现和音量键的同步

1,上图: 2,代码: MainActivity.java package com.hero.zhaoq.seekbarchangeddemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObse

android取消点击音量键弹出音量调节界面

比如在viewpager中点击音量键调节上一页下一页,return true就可以取消音量界面的显示 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (voiceRead.equals("open")) { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { vp.setCurrentItem(vp.getCurrentItem()+1); return tr

Xamarin Android 监听音量键(下)

上篇在 MainActivity 中重写了按键事件(OnKeyDown),获取了音量键键值并打印了出来,当然,手机物理按键和虚拟按键(音量键.返回键.菜单键等)均可通过该按键事件被捕获. 但是,按键重写在 MainActivity 中,音量键按下时执行的方法在其他页面中. 作者冒出了一个不成熟的想法:利用(publish-subscribe)模式,在 MainActivity 中定义发布者(publish),实例化后层层传递到达 我的页面中,,再将实例化后的订阅者(subscribe)连接上.如

Android audioManager解决MediaPlayer AudioTrack 调节音量问

在听筒模式下 am.setSpeakerphoneOn(false); setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); am.setMode(AudioManager.MODE_IN_CALL); 我用Mediaplayer AudioTrack调节音量总是失败 at.setStereoVolume(vol, vol); player.setVolume(vol,vol); 后来 决定用AudioManager来调节音量 Audio

android5.1 修改音量键绑定多媒体声音

修改此文件frameworks/base/media/java/android/media/AudioService.java中函数 private int getActiveStreamType(int suggestedStreamType) { ............... ............... else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { /* carroll 修改音量键默认调节

解决Cocos2d-x进入游戏后,调节音量键不管用,要按一下返回键,音量键才可用的Bug

我们知道 处理按钮事件都是在view里做的, 而我们游戏的主界面继承了Cocos2dxGLSurfaceView 所以 应该是这个文件里对按钮的处理有问题,于是我们找到这个文件, 这个显然是2d-x的源文件,但我们抱着试一试的心理 加上自己写的按钮处理事件. 结果加上之后没有任何效果,跟没加一样,所以我们知道 不是这里的问题. 于是 我们再思考,根据那些错误提示. 具体我们也看不懂为什么,但是在进入游戏后点击调节音量键,就会出现这一行代码,从上往下看 不是 EditText就是 Cocos2dx