Android音量调节修改

前言

今日公司,安卓设备的音量显示不正常,让我来修复这个bug,现在已修复,做个博客,记录一下,以后碰到类似一下子就好解决。

Android音量调节相关

路径

frameworks\base\services\core\java\com\android\server\audio\AudioService.java

这个文件包含了关于android音量调节的代码逻辑。

问题

音量调节那里,调小会直接变成0,而且过程我发现他会有跳动的感觉。

思路

找到apk,调用这个文件的接口,添加打印了解对应逻辑。

找到问题点

  • 音量数值对不上
  • 音量多次调用onSetStreamVolume函数(每个音乐流都调用一次)

解决问题

  • 数值对不上(修改apk与底层数值对应关系)

  • 多次调用(把对应干扰流都屏蔽掉)

setStreamVolume接口

/**
     * 设置音频流的音量。
     *
     * @param streamType 要设置音量的音频流类型,例如 AudioManager.STREAM_MUSIC。
     * @param index 要设置的音量索引,通常是一个在音频流范围内的整数值。
     * @param flags 设置标志,包括有关音量设置的额外信息,例如 AudioManager.FLAG_FIXED_VOLUME。
     * @param callingPackage 调用该方法的应用程序的包名。
     * @param caller 调用者的标识。
     * @param uid 调用者的用户标识。
     * @param hasModifyAudioSettings 是否有修改音频设置的权限。
     */
    private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
                                 String caller, int uid, boolean hasModifyAudioSettings) {
        if (DEBUG_VOL) {
            Log.d(TAG, "setStreamVolume(stream=" + streamType + ", index=" + index
                    + ", calling=" + callingPackage + ")");
        }
        if(streamType != 3){
            return ;
        }

        // 如果使用了固定音量,直接返回
        if (mUseFixedVolume) {
            return;
        }
        
        Log.d(TAG, "************************");

        // 确保音频流类型有效
        ensureValidStreamType(streamType);

        // 获取音频流类型别名和对应的音量流状态
        int streamTypeAlias = mStreamVolumeAlias[streamType];
        VolumeStreamState streamState = mStreamStates[streamTypeAlias];

        // 获取与音频流类型别名对应的设备
        final int device = getDeviceForStream(streamType);
        int oldIndex;

        // 如果不是 A2DP 设备,并且标志包含了 AudioManager.FLAG_BLUETOOTH_ABS_VOLUME,
        // 则跳过 A2DP 绝对音量控制请求
        if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
                && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
            return;
        }

        // 如果是系统调用(例如硬件按键),检查当前用户以正确处理用户限制
        if (uid == android.os.Process.SYSTEM_UID) {
            uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
        }

        // 验证调用包和 app op 权限
        if (!checkNoteAppOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)) {
            return;
        }

        // 在 Android N 及以上版本,如果音量调整将切换 Zen 模式,
        // 则检查是否已授予调用包通知策略的访问权限
        if (isAndroidNPlus(callingPackage)
                && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
                && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
            throw new SecurityException("Not allowed to change Do Not Disturb state");
        }

        // 如果音量调整在当前 Do Not Disturb 模式下不允许,则直接返回
        if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
            return;
        }

        synchronized (mSafeMediaVolumeStateLock) {
            // 重置任何挂起的音量命令
            mPendingVolumeCommand = null;

            // 获取旧的音量索引
            oldIndex = streamState.getIndex(device);

            // 对索引进行重新缩放
            Log.d(TAG, "缩放前 index=+"+index);
            index = index * 10;//rescaleIndex(index * 10, streamType, streamTypeAlias);
            Log.d(TAG, "缩放后 index=+"+index);

            // 如果音频流类型别名是 STREAM_MUSIC
            // 且设备是 A2DP 设备并且标志不包含 AudioManager.FLAG_BLUETOOTH_ABS_VOLUME,
            // 则发送 Avrcp 绝对音量索引的消息
            if (streamTypeAlias == AudioSystem.STREAM_MUSIC
                    && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
                    && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
                if (DEBUG_VOL) {
                    Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
                            + "stream=" + streamType);
                }
                mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
            }

            // 如果设备是 HEARING_AID 设备且音频流是 HEARING_AID 类型,
            // 则发送设置 HEARING_AID 音量索引的消息
            if (device == AudioSystem.DEVICE_OUT_HEARING_AID
                    && streamType == getHearingAidStreamType()) {
                Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
                        + " stream=" + streamType);
                mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
            }

            // 如果音频流类型别名是 STREAM_MUSIC,发送设置系统音频音量的消息
            if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
            }

            // 清除 AudioManager.FLAG_FIXED_VOLUME 标志
            flags &= ~AudioManager.FLAG_FIXED_VOLUME;

            // 如果音频流类型别名是 STREAM_MUSIC 且是固定音量设备,则设置 AudioManager.FLAG_FIXED_VOLUME 标志
            if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
                flags |= AudioManager.FLAG_FIXED_VOLUME;

                // 对于固定音量设备,音量要么为 0,要么为允许的最大值
                if (index != 0) {
                    if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
                            mSafeMediaVolumeDevices.contains(device)) {
                        index = safeMediaVolumeIndex(device);
                    } else {
                        index = streamState.getMaxIndex();
                    }
                }
                Log.d(TAG,"STREAM_MUSIC   index = " + index);
            }

            // 如果音量超出安全范围,显示安全音量警告,并设置挂起的音量命令
            if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
                mVolumeController.postDisplaySafeVolumeWarning(flags);
                mPendingVolumeCommand = new StreamVolumeCommand(
                        streamType, index, flags, device);
            } else {
                // 否则,调用 onSetStreamVolume 设置音量
                onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings);
                // 获取最终的音量索引
                index = mStreamStates[streamType].getIndex(device);
                Log.d(TAG, "获取最终的音量索引"+ "index=" + index + ")");
            }
        }

问题 1关键点
在这里插入图片描述
问题 2关键点
在这里插入图片描述

结束

轻描淡写的俩个问题,看上去简单,如果你什么也不知道情况下调试,你就知道了。

刚解决完,马上发一篇博客,帮助更多的人,因为有问题找不到答案真的很无助,做点力所能及的事情吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/353955.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode力扣题解(随机每日一题)——买钢笔和铅笔的方案数

题目链接 2240. 买钢笔和铅笔的方案数 - 力扣(LeetCode) 题目描述 给你一个整数 total ,表示你拥有的总钱数。同时给你两个整数 cost1 和 cost2 ,分别表示一支钢笔和一支铅笔的价格。你可以花费你部分或者全部的钱,…

LandrayOA内存调优 / JAVA内存调优 / Tomcat web.xml 超时时间调优实战

目录 一、背景说明 二、LandrayOA / Tomcat 内存调优 2.1 \win64\tomcat\conf\web.xml 文件调优 2.2 \win64\tomcat\bin\catalina64.bat 文件调优 一、背景说明 随着系统的使用时间越来越长,数据量越多,发现系统的有些功能越来越慢&…

C语言基础:写一个函数,输入一行字符,将此字符串最长的单词输出

方法一&#xff1a; #include<string.h> int find_longest(char line[])//把数组传过来 {int is_alphabetic(char word);int i 0;int length 0;//统计每个字符串的长度int max 0;//比max长就把值赋值给maxint place 0;//最长单词的起始位置int point;//每个字符串第…

机器学习的数据库积累........

https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md ​​​​​​​ 另一个database:&#xff08;网址:Object Detection Made Easy with TensorFlow Hub: Tutorial&#xff09; Object Detection Made Easy with Ten…

Android底部导航栏创建——ViewPager + RadioGroup

Android底部导航栏有多种实现方式&#xff0c;本文详解其中的ViewPager RadioGroup方式的实现步骤。 我们先来看以下看一下最终做出的效果&#xff0c;使大家有个基本概念。 本结构特点&#xff1a; 1&#xff0c;ViewPager部分触摸左右滑动切换页面&#xff0c;RadioGroup部…

XXL-JOB

SpringTask这种任务只能放在单机节点下&#xff0c;就是说一个程序只跑一份的情况下&#xff0c;用SpringTask做定时任务没有什么问题&#xff0c;而且很好用&#xff0c;但是一旦这个程序需要运行多份&#xff0c;定时任务用SpringTask就不行了。多份代码重复执行了。 要解决…

React中文官网已经搬迁了,原网址内容将不再更新

注意1&#xff1a;React中文官网已经搬迁至-React 官方中文文档&#xff0c;原网址内容将不再更新 注意2&#xff1a;React官网已经将React的定义由“用于构建用户界面的 JavaScript 库”更改为“用于构建 Web 和原生交互界面的库”。

Power ModeII 插件的下载与使用-----idea

下载 Marketplace里面搜索下载即可 使用 下载后重启软件就可以用了 下面是一些关于Power ModeII &#xff0c;我的个性化设置截图 以及相关设置解释 插件或扩展的设置面板【用于给代码编辑器或集成开发环境&#xff08;IDE&#xff09;添加视觉效果】 主要设置 ENTER POWE…

GEE数据集——2024 年日本海地震的紧急观测数据

2024 年日本海地震的紧急观测数据 2024 年日本海地震发生在 2024 年 1 月 1 日下午 4:00 后&#xff08;日本时间&#xff09;&#xff0c;造成了重大损失&#xff0c;包括多处建筑物倒塌、山体滑坡和火灾。应日本国内防灾机构的请求&#xff0c;JAXA 利用 ALOS-2 对灾害发生当…

Jenkins邮件推送配置

目录 涉及Jenkins插件&#xff1a; 邮箱配置 什么是授权码 在第三方客户端/服务怎么设置 IMAP/SMTP 设置方法 POP3/SMTP 设置方法 获取授权码&#xff1a; Jenkins配置 从Jenkins主面板System configuration>System进入邮箱配置 在Email Extension Plugin 邮箱插件…

操作日志应记录编辑的前后内容变化

总体思路是增加一个注解类&#xff0c;将注解加到要进行记录变化的Java类属性上却可。 上代码&#xff1a; 1. 实现注解类&#xff1a; Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface FieldName {String value();boolean isIgnoreNull()…

六、VTK创建平面vtkPlaneSource

vtkPlaneSource创建位于平面中的四边形数组 先看看效果图: vtkPlaneSource 创建一个 m x n 个四边形数组,这些四边形在平面中排列为规则平铺。通过指定一个原点来定义平面,然后指定另外两个点,这两个点与原点一起定义平面的两个轴。这些轴不必是正交的 - 因此您可以创建平行…

基于yolov5的数据集自动标注功能脚本工具【附代码】

近年来&#xff0c;随着深度学习的迅猛发展&#xff0c;计算机视觉领域取得了巨大的突破。其中&#xff0c;目标检测是计算机视觉中的一个重要任务&#xff0c;它在许多应用领域中起到了至关重要的作用。然而&#xff0c;目标检测所需的大量标注数据集的制作却是一项耗时且繁琐…

FlashInternImage实战:使用 FlashInternImage实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

mac配置L2TP连接公司内网

1. 打开系统设置 2. 打开网络 3. 点击网络页面其他服务右下角三个点&#xff0c;添加VPN配置中的L2TP 4. 配置VPN&#xff0c;服务器填写公司的服务器ip&#xff0c;共享密钥没有可以随便填写 5. 打开终端编辑文件 sudo vim /etc/ppp/opt…

Linux系统简介及发展历史

Linux的概况 Linux是自由软件 Linux是一种类UNIX操作系统。Linux内核由Linus Torvalds在1991年发布。在加上用户空间的应用程序之后&#xff0c;成为Linux操作系统 只要遵循GNU通用公共许可证&#xff08;GPL&#xff09;&#xff0c;任何个人和机构都可以自由地使用Linux的所…

网络安全02--负载均衡下的webshell连接

目录 一、环境准备 1.1ubentu虚拟机一台&#xff0c;docker环境&#xff0c;蚁剑 1.2环境压缩包&#xff08;文件已上传资源&#xff09;&#xff1a; 二、开始复原 2.1上传ubentu&#xff1a; 2.2解压缩 2.3版本20没有docker-compose手动下载&#xff0c;包已上传资源 …

Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)

Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心&#xff0c;Kotlin&#xff08;2&#xff09; 在 Android ScaleGestureDetector检测双指缩放Bitmap基于Matrix动画移动到双指捏合中心点ImageView区域中心&#xff0c;Kotlin-CSDN博客 …

vue+Element UI实现省市区镇四级联动

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 在一些需要填写地址的前端页面中&#xff0c;总是少不了需要填写地址的级联选择器&#xff0c;类似这样的&…

【Linux】第三十六站:信号

文章目录 一、信号的概念1.信号概念2.前台与后台进程3.信号的处理4.硬件层面5.信号与我们的代码是异步的 二、信号的产生1.产生的方式2.键盘组合键3.kill命令4.系统调用4.1 kill系统调用4.2 raise4.3 abort 5.异常软件条件5.1 异常产生信号5.2 alarm&#xff08;软件条件产生信…