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

相关文章

PostgreSQL 默认隔离级别的设置

《PostgreSQL默认隔离级别的设置》PostgreSQL的默认事务隔离级别是读已提交,这是其事务处理系统的基础行为模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一 默认隔离级别概述1.1 默认设置1.2 各版本一致性二 读已提交的特性2.1 行为特征2.2

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

mtu设置多少网速最快? 路由器MTU设置最佳网速的技巧

《mtu设置多少网速最快?路由器MTU设置最佳网速的技巧》mtu设置多少网速最快?想要通过设置路由器mtu获得最佳网速,该怎么设置呢?下面我们就来看看路由器MTU设置最佳网速的技巧... 答:1500 MTU值指的是在网络传输中数据包的最大值,合理的设置MTU 值可以让网络更快!mtu设置可以优化不同的网

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

VSCode设置python SDK路径的实现步骤

《VSCode设置pythonSDK路径的实现步骤》本文主要介绍了VSCode设置pythonSDK路径的实现步骤,包括命令面板切换、settings.json配置、环境变量及虚拟环境处理,具有一定... 目录一、通过命令面板快速切换(推荐方法)二、通过 settings.json 配置(项目级/全局)三、

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R