Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to set absolute volume and relative volume in Android

2025-04-13 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces how to set the absolute volume and relative volume in Android. The content is very detailed. Interested friends can use it for reference. I hope it will be helpful to you.

Foreword:

Absolute volume: the mobile phone does not deal with the volume, only tells the current volume to the headset, and the headset handles the volume.

Relative volume: when dealing with the phone, the headset is not sure whether it is the highest by default, or whether there is a default volume that is handled according to the previously set absolute volume.

The mobile phone volume converts the absolute volume, and there will be a calculation process here, that is, the phone side calculates the percentage of the current volume and the maximum volume and sets it to the headset, and the headset receives the percentage to deal with it. Otherwise, the volume range of each phone is different, and it will be difficult to adapt without normalization.

When the volume is adjusted through the volume button, it is distributed through the input event, input distributes the event to mediassesion, and mediasession calls audiomanager's adjustStreamVolume to adjust the volume.

When you adjust the volume by dragging the volume bar, settings app calls audiomanager's setStreamVolume to adjust the volume.

The process of adjustStreamVolume is similar to that of setStreamVolume, and then just look at setStreamVolume.

SetStreamVolume calls / / frameworks/base/media/java/android/media/AudioManager.javapublic void setStreamVolume (int streamType, int index, int flags) {final IAudioService service = getService (); try {service.setStreamVolume (streamType, index, flags, getContext (). GetOpPackageName ()); / / audiomanager calls audioservice's setStreamVolume} catch (RemoteException e) {throw e.rethrowFromSystemServer ();}}

The procedure for calling audioservice:

/ frameworks/base/services/core/java/com/android/server/audio/AudioService.javaprivate void setStreamVolume (int streamType, int index, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings) {ensureValidStreamType (streamType); int streamTypeAlias = mStreamVolumeAlias [streamType]; VolumeStreamState streamState = mStreamStates [streamTypeAlias]; inal int device = getDeviceForStream (streamType); / / get device int oldIndex; synchronized (mSafeMediaVolumeStateLock) {/ / reset any pending volume command mPendingVolumeCommand = null corresponding to streamType OldIndex = streamState.getIndex (device); android.media.AudioServiceInjector.mOriginalIndexWhenSetStreamVolume = index; index = rescaleIndex (index * 10, streamType, streamTypeAlias); / / set absolute volume if (streamTypeAlias = = AudioSystem.STREAM_MUSIC & & AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains (device) & & (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) = = 0) {mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex (index / 10) } if (streamTypeAlias = = AudioSystem.STREAM_MUSIC) {setSystemAudioVolume (oldIndex, index, getStreamMaxVolume (streamType), flags); / / here is related to hdmi, never mind} flags & = ~ AudioManager.FLAG_FIXED_VOLUME; if (streamTypeAlias = = AudioSystem.STREAM_MUSIC & & isFixedVolumeDevice (device)) {flags | = AudioManager.FLAG_FIXED_VOLUME / / volume is either 0 or max allowed for fixed volume devices if (index! = 0) {if (mSafeMediaVolumeState = = SAFE_MEDIA_VOLUME_ACTIVE & & mSafeMediaVolumeDevices.contains (device)) {index = safeMediaVolumeIndex (device);} else {index = streamState.getMaxIndex () } if (! checkSafeMediaVolume (streamTypeAlias, index, device) {mVolumeController.postDisplaySafeVolumeWarning (flags)) {mVolumeController.postDisplaySafeVolumeWarning (flags); / / this should be a safety reminder, such as mPendingVolumeCommand = new StreamVolumeCommand (streamType, index, flags, device);} else {onSetStreamVolume (streamType, index, flags, device, caller, hasModifyAudioSettings) / / call onSetStreamVolume to set the volume index = mStreamStates [streamType] .getIndex (device);} sendVolumeUpdate (streamType, oldIndex, index, flags, device);}

The role of onSetStreamVolume and sendVolumeUpdate:

OnSetStreamVolume-> set the volume to the bottom and handle some mute logic.

SendVolumeUpdate-> notify ui to update the volume value

Insert a process to mute automatically when the volume is set to 0: / frameworks/base/services/core/java/com/android/server/audio/AudioService.javaprivate void onSetStreamVolume (int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings) {final int stream = mStreamVolumeAlias [streamType]; setStreamVolumeInt (stream, index, device, false, caller, hasModifyAudioSettings) / / set the volume to the underlying / / setting volume on ui sounds stream type also controls silent mode if (flags & AudioManager.FLAG_ALLOW_RINGER_MODES)! = 0) | | (stream = = getUiSoundsStreamType ()) {int ringerMode = getNewRingerMode (stream, index, flags); / / get ringmode miuiRingerMode = miui.util.AudioManagerHelper.getValidatedRingerMode (mContext, miuiRingerMode); / / get ringmode setRingerMode (ringerMode, TAG + ".onSetStreamVolume", false / * external*/) / / set ringmode}} private int getNewRingerMode (int stream, int index, int flags) {if (flags & AudioManager.FLAG_ALLOW_RINGER_MODES)! = 0) | (stream = = getUiSoundsStreamType ()) {int newRingerMode If (index = = 0) {/ / if the volume is set to 0 / / if there is vibration, set ringmode to vibration mode, otherwise determine whether volumeDownToEnterSilent decides to set mute or not mute newRingerMode = mHasVibrator? AudioManager.RINGER_MODE_VIBRATE: mVolumePolicy.volumeDownToEnterSilent? AudioManager.RINGER_MODE_SILENT: AudioManager.RINGER_MODE_NORMAL;} else {newRingerMode = AudioManager.RINGER_MODE_NORMAL; / / set ringmode to non-mute} return newRingerMode;} return getRingerModeExternal () if the volume is not 0 } set absolute volume: postSetAvrcpAbsoluteVolumeIndex// frameworks/base/services/core/java/com/android/server/audio/AudioDeviceBroker.javavoid postSetAvrcpAbsoluteVolumeIndex (int index) {sendIMsgNoDelay (MSG_I_SET_AVRCP_ABSOLUTE_VOLUME, SENDMSG_REPLACE, index);} / / receive message MSG_I_SET_AVRCP_ABSOLUTE_VOLUME, call mBtHelper.setAvrcpAbsoluteVolumeIndex (msg.arg1) / / frameworks/base/services/core/java/com/android/server/audio/BtHelper.javasynchronized void setAvrcpAbsoluteVolumeIndex (int index) {mA2dp.setAvrcpAbsoluteVolume (index);} Bluetooth side absolute volume processing: / / vendor/qcom/opensource/commonsys/packages/apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpService.javapublic void setAvrcpAbsoluteVolume (int volume) {if (mFactory.getAvrcpTargetService ()! = null) {mFactory.getAvrcpTargetService () .sendVolumeChanged (volume); return } if (ApmConstIntf.getLeAudioEnabled ()) {VolumeManagerIntf mVolumeManager = VolumeManagerIntf.get (); mVolumeManager.setMediaAbsoluteVolume (volume); return;} synchronized (mBtAvrcpLock) {if (mAvrcp_ext! = null) {mAvrcp_ext.setAbsoluteVolume (volume); return;} if (mAvrcp! = null) {mAvrcp.setAbsoluteVolume (volume) } / / vendor/qcom/opensource/commonsys/bluetooth_ext/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.javapublic void setAbsoluteVolume (int volume) {Message msg = mHandler.obtainMessage (MSG_SET_ABSOLUTE_VOLUME, volume, 0); mHandler.sendMessage (msg);} after receiving the message MSG_SET_ABSOLUTE_VOLUME, call the following case MSG_SET_ABSOLUTE_VOLUME: {int avrcpVolume = convertToAvrcpVolume (msg.arg1) .} / / calculate avrcpVolumeprivate int convertToAvrcpVolume (int volume) {if (mAudioStreamMax = = 150) {return (int) Math.round ((double) volume*AVRCP_MAX_VOL/mAudioStreamMax);} return (int) Math.ceil ((double) volume*AVRCP_MAX_VOL/mAudioStreamMax);}

As you can see here, the volume transmitted from the Bluetooth side to the headset is actually a percentage.

The process of switching from relative volume to absolute volume:

Bluetooth APP has a NotificationReceiver. When the absolute volume switch changes, NotificationReceiver will receive the message and do the following:

Private class NotificationReceiver extends BroadcastReceiver {public void onReceive (Context context, Intent intent) {if (ABS_VOLUME_ACTION.equals (intent.getAction () {handleDeviceAbsVolume (mac, value);} / / handleDeviceAbsVolume will do the corresponding processing and send the volume value to the headset side.

There will be log printing every time you switch here, log mask: handleDeviceAbsVolume | setVolumeNative

After switching, the playback sound will call checkAndSetVolume to set the volume value to the maximum to ensure that there is no volume processing on the phone side.

Switching from absolute volume to relative volume processing:

As above, the Bluetooth APP NotificationReceiver receives a message that the absolute volume switch is off and sends the message to the headset side. Then the audio side is called to set the volume of the stream.

Log mask: handleDeviceAbsVolume | setStreamVolume

After switching, playing the sound will call checkAndSetVolume to set the volume value to the current actual volume value.

What is Android? Android is a free and open source operating system based on the Linux kernel, mainly used in mobile devices, such as smartphones and tablets, led and developed by Google and the Open Mobile Alliance.

So much for sharing the absolute volume and relative volume settings in Android. I hope the above content can be of some help and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report