AndroidQ 设置静音模式后按音量上键不能调节音量大小

2023-10-30 10:10

本文主要是介绍AndroidQ 设置静音模式后按音量上键不能调节音量大小,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AndroidQ按音量键,默认会调出meida的音量,但是客户要求将默认调出ringer。改为默认ringer后,发现点击音量条上方的ringer_icon,设置为静音模式后,在按音量上键,不能调节音量大小了。

关于音量这块,framework中是与AudioService、AudioManager、AudioSystem相关,音量弹框的界面处理是在SystemUI下,有个volumn的文件夹。

要解此问题,很显然要从AudioService入手,因为音量的加减和AudioProfile模式都是在AudioServie处理好之后,将消息发给SystemUI,SystemUI去做界面上的更新。

AudioService中处理音量的关键方法adjustSuggestedStreamVolume–>adjustStreamVolume
adjustSuggestedStreamVolume根据名称可以猜到是Suggested,建议的音量调整。该方法主要是将传递进来的suggestedStreamType,通过etActiveStreamType方法计算出来真正要调整的音量类型。前面说的客户要求将默认的音量类型由media改为ringer关键就是在这个方法中处理的。
在这里插入图片描述
adjustSuggestedStreamVolume计算出来真正需要调整的音量类型后就调用adjustStreamVolume,流程转到adjustStreamVolume中。

这里先说一个AudioService中的内部类VolumeStreamState,每种音量类型(STREAM_VOICE_CALL、STREAM_RING、STREAM_MUSIC。。。)都会实例化一个VolumeStreamState对象,其中int mStreamType就是音量类型,还有一个SparseIntArray mIndexMap,这里有个device的概念,比如说STREAM_MUSIC类型,music可以通过麦克、耳机(有线、蓝牙耳机)等很多设备播放,这个SparseIntArray就是保存的该种音量类型在不同设备上的音量大小。

在这里插入图片描述
流程转到adjustStreamVolume中,首先该方法有一些条件判断,不满足的直接return。通过重重判断后来到第一个关键的地方:
在这里插入图片描述
计算步长,就是本次音量调整调多少,log看到是以10为步长的。比如15级的音量,通过音量键调大小是70、80、90等等这样的大小,step是以10来增加的。
再下来就进入了RingerMode的相关处理了
在这里插入图片描述
跟踪getUiSoundsStreamType的实现,就是STREAM_RING

/** @see AudioManager#getUiSoundsStreamType()  */public int getUiSoundsStreamType() {return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];}private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALLAudioSystem.STREAM_RING,            // STREAM_SYSTEMAudioSystem.STREAM_RING,            // STREAM_RINGAudioSystem.STREAM_MUSIC,           // STREAM_MUSICAudioSystem.STREAM_ALARM,           // STREAM_ALARMAudioSystem.STREAM_RING,            // STREAM_NOTIFICATIONAudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCOAudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCEDAudioSystem.STREAM_RING,            // STREAM_DTMFAudioSystem.STREAM_MUSIC,           // STREAM_TTSAudioSystem.STREAM_MUSIC            // STREAM_ACCESSIBILITY};

来看下checkForRingerModeChange的逻辑,该方法是case不同的mode,我们重点关注RINGER_MODE_SILENT。mIsSingleVolume为false,那就进到else if中
!mVolumePolicy.volumeUpToExitSilent =====》添加一个hint标志位
else ====》切换到振动模式(振动模式下增加音量就会切到normal模式,然后就可以正常调整音量了)
在这里插入图片描述
现在暂时将mVolumePolicy.volumeUpToExitSilent的来源忽略,继续跟踪adjustStreamVolume后面的逻辑。
在这里插入图片描述
checkForRingerModeChange的计算结果会影响adjustVolume的boolean值。
调整音量值的是在我们上面提到的内部类VolumeStreamState中,
在这里插入图片描述
adjustStreamVolume方法的最后一行是调用sendVolumeUpdate

// UI update and Broadcast Intentprotected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device){streamType = mStreamVolumeAlias[streamType];if (streamType == AudioSystem.STREAM_MUSIC) {flags = updateFlagsForTvPlatform(flags);if ((device & mFullVolumeDevices) != 0) {flags &= ~AudioManager.FLAG_SHOW_UI;}}mVolumeController.postVolumeChanged(streamType, flags);}public void postVolumeChanged(int streamType, int flags) {if (mController == null)return;try {mController.volumeChanged(streamType, flags);} catch (RemoteException e) {Log.w(TAG, "Error calling volumeChanged", e);}}

这里的volumeChanged就是向SystemUI去通知音量变化了,SystemUI收到该通知就会读取系统音量:
frameworks\base\packages\SystemUI\src\com\android\systemui\volume\VolumeDialogControllerImpl.java代码:
在这里插入图片描述
在这里插入图片描述
这里的getAudioManagerStreamVolume,最后就是调用AudioService的getLastAudibleStreamVolume,即上面提到的VolumeStreamType中put的值

/** Get last audible volume before stream was muted. */public int getLastAudibleStreamVolume(int streamType) {ensureValidStreamType(streamType);int device = getDeviceForStream(streamType);return (mStreamStates[streamType].getIndex(device) + 5) / 10;}

到此是音量调整从AudioService到SystemUI中的逻辑。
对于我们这个问题,静音模式下不能调节音量的问题,我们回到前面忽略的关键判断:checkForRingerModeChange方法中的mVolumePolicy.volumeUpToExitSilent,从名称上就好理解,音量上键退出静音模式,追踪mVolumePolicy的赋值

@Overridepublic void setVolumePolicy(VolumePolicy policy) {enforceVolumeController("set volume policy");if (policy != null && !policy.equals(mVolumePolicy)) {mVolumePolicy = policy;if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);}}

public方法,显然是被外界调用的,framework/base下搜索,竟然是在SystemUI下的VolumeDialogComponent.java中调用
看下该类是如果实例化VolumePolicy对象的:
在这里插入图片描述
果然DEFAULT_VOLUME_UP_TO_EXIT_SILENT配置的是false,改为true就可以在静音模式下按音量上面,先切换到振动模式,再按音量上键,进入normal模式,就可以正常调节音量了。

这篇关于AndroidQ 设置静音模式后按音量上键不能调节音量大小的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/307179

相关文章

Nginx location匹配模式与规则详解

《Nginxlocation匹配模式与规则详解》:本文主要介绍Nginxlocation匹配模式与规则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、环境二、匹配模式1. 精准模式2. 前缀模式(不继续匹配正则)3. 前缀模式(继续匹配正则)4. 正则模式(大

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

PyCharm如何设置新建文件默认为LF换行符

《PyCharm如何设置新建文件默认为LF换行符》:本文主要介绍PyCharm如何设置新建文件默认为LF换行符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm设置新建文件默认为LF换行符设置换行符修改换行符总结PyCharm设置新建文件默认为LF

SpringBoot如何通过Map实现策略模式

《SpringBoot如何通过Map实现策略模式》策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这... 目录前言底层机制解析Spring的集合类型自动装配@Resource注解的行为实现原理使用直接使用M

Linux上设置Ollama服务配置(常用环境变量)

《Linux上设置Ollama服务配置(常用环境变量)》本文主要介绍了Linux上设置Ollama服务配置(常用环境变量),Ollama提供了多种环境变量供配置,如调试模式、模型目录等,下面就来介绍一... 目录在 linux 上设置环境变量配置 OllamPOgxSRJfa手动安装安装特定版本查看日志在

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3