Android点击和触摸音量小的问题(问题追踪)

news2024/9/22 11:37:20

有客户反馈:A14触摸声音没有

于是乎,追踪setting打开触摸声音的代码:

 @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        if (preference == mVibrateWhenRinging) {
            Settings.System.putInt(getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING,
                    mVibrateWhenRinging.isChecked() ? 1 : 0);
        } else if (preference == mDtmfTone) {
            Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
            mDtmfTone.isChecked() ? 1 : 0);

        } else if (preference == mSoundEffects) {
            if (mSoundEffects.isChecked()) {
                mAudioManager.loadSoundEffects();
            } else {
                mAudioManager.unloadSoundEffects();
            }
            Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
            mSoundEffects.isChecked() ? 1 : 0);

        }

可以看出来是用:Settings.System.SOUND_EFFECTS_ENABLED这个setting值来控制的。

利用adb看这个值:

确实是开启了的,于是怀疑跑的过程中哪里中断了(可能谷歌加了些判断逻辑),于是继续追:

在View.java里面的触摸声音代码:

    /**
     * Set whether this view should have sound effects enabled for events such as
     * clicking and touching.
     *
     * <p>You may wish to disable sound effects for a view if you already play sounds,
     * for instance, a dial key that plays dtmf tones.
     *
     * @param soundEffectsEnabled whether sound effects are enabled for this view.
     * @see #isSoundEffectsEnabled()
     * @see #playSoundEffect(int)
     * @attr ref android.R.styleable#View_soundEffectsEnabled
     */
    public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
        setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
    }

    /**
     * @return whether this view should have sound effects enabled for events such as
     *     clicking and touching.
     *
     * @see #setSoundEffectsEnabled(boolean)
     * @see #playSoundEffect(int)
     * @attr ref android.R.styleable#View_soundEffectsEnabled
     */
    @ViewDebug.ExportedProperty
    public boolean isSoundEffectsEnabled() {
        return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
    }

看到这2个方法我就有底了。很明显,我们要查看isSoundEffectsEnabled的调用关系。

    /**
     * Play a sound effect for this view.
     *
     * <p>The framework will play sound effects for some built in actions, such as
     * clicking, but you may wish to play these effects in your widget,
     * for instance, for internal navigation.
     *
     * <p>The sound effect will only be played if sound effects are enabled by the user, and
     * {@link #isSoundEffectsEnabled()} is true.
     *
     * @param soundConstant One of the constants defined in {@link SoundEffectConstants}
     */
    public void playSoundEffect(int soundConstant) {
        if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
            return;
        }
        mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
    }

接着我们看谁调用了它,找到在AudioServeice.java中

    /** @see AudioManager#playSoundEffect(int) */
    public void playSoundEffect(int effectType) {
        playSoundEffectVolume(effectType, -1.0f);
    }

    /** @see AudioManager#playSoundEffect(int, float) */
    public void playSoundEffectVolume(int effectType, float volume) {
        sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
        effectType, (int) (volume * 1000), null, 0);
    }

发送MSG_PLAY_SOUND_EFFECT消息,发送的消息在AudioHandler的handleMessage中处理:

public class AudioService extends IAudioService.Stub
        implements AccessibilityManager.TouchExplorationStateChangeListener,
            AccessibilityManager.AccessibilityServicesStateChangeListener,
            AudioSystemAdapter.OnRoutingUpdatedListener,
            AudioSystemAdapter.OnVolRangeInitRequestListener {
    private SoundEffectsHelper mSfxHelper;
    /** Handles internal volume messages in separate volume thread. */
    private class AudioHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_PLAY_SOUND_EFFECT:
                    mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
                    break;
        }
    }
}

调用SoundEffectsHelper的playSoundEffect方法

//frameworks/base/service/java/com/android/server/audio/SoundEffectsHelper.java
class SoundEffectsHelper {
    /*package*/ void playSoundEffect(int effect, int volume) {
        sendMsg(MSG_PLAY_EFFECT, effect, volume, null, 0);
    }
}

发送MSG_PLAY_EFFECT消息:

//frameworks/base/service/java/com/android/server/audio/SoundEffectsHelper.java
class SoundEffectsHelper {
    private class SfxHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_PLAY_EFFECT:
                    final int effect = msg.arg1, volume = msg.arg2;
                    onLoadSoundEffects(new OnEffectsLoadCompleteHandler() {
                        @Override
                        public void run(boolean success) {
                            if (success) {
                                onPlaySoundEffect(effect, volume);
                            }
                        }
                    });
                    break;
            }
        }
    }
}

调用onLoadSoundEffects方法:

//frameworks/base/service/java/com/android/server/audio/SoundEffectsHelper.java
class SoundEffectsHelper {
    private SoundPool mSoundPool;
    private void onLoadSoundEffects(OnEffectsLoadCompleteHandler onComplete) {
        if (mSoundPoolLoader != null) {
            // Loading is ongoing.
            mSoundPoolLoader.addHandler(onComplete);
            return;
        }
        if (mSoundPool != null) {
            if (onComplete != null) {
                onComplete.run(true /*success*/);
            }
            return;
        }
 
 
        logEvent("effects loading started");
        mSoundPool = new SoundPool.Builder()
                .setMaxStreams(NUM_SOUNDPOOL_CHANNELS)
                .setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .build())
                .build(); //创建SoundPool对象
        loadSoundAssets(); //加载声音资料
 
 
        mSoundPoolLoader = new SoundPoolLoader(); //创建SoundPoolLoader对象
        mSoundPoolLoader.addHandler(new OnEffectsLoadCompleteHandler() { //增加OnEffectsLoadComplete Handler
            @Override
            public void run(boolean success) {
                mSoundPoolLoader = null;
                if (!success) {
                    Log.w(TAG, "onLoadSoundEffects(), Error while loading samples");
                    onUnloadSoundEffects();
                }
            }
        });
        mSoundPoolLoader.addHandler(onComplete); //增加onComplete Handler
 
 
        int resourcesToLoad = 0;
        for (Resource res : mResources) {
            String filePath = getResourceFilePath(res);
            int sampleId = mSoundPool.load(filePath, 0);
            if (sampleId > 0) {
                res.mSampleId = sampleId;
                res.mLoaded = false;
                resourcesToLoad++;
            } else {
                logEvent("effect " + filePath + " rejected by SoundPool");
                Log.w(TAG, "SoundPool could not load file: " + filePath);
            }
        }
 
 
        if (resourcesToLoad > 0) {
            sendMsg(MSG_LOAD_EFFECTS_TIMEOUT, 0, 0, null, SOUND_EFFECTS_LOAD_TIMEOUT_MS);
        } else {
            logEvent("effects loading completed, no effects to load");
            mSoundPoolLoader.onComplete(true /*success*/);
        }
    }
}

直到追到这里我才惊觉,好像每个流程都正常!!!

于是我放在耳朵边上听,微弱的触摸音传出的时候,我心态崩了

但是问题还要继续,客户是上帝,所以要解决的是触摸声音小的问题

追踪SoundEffectsHelper.java的代码时发现:

  SoundEffectsHelper(Context context, Consumer<PlayerBase> playerAvailableCb) {
        mContext = context;
        mSfxAttenuationDb = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_soundEffectVolumeDb);
        mPlayerAvailableCb = playerAvailableCb;
        startWorker();
    }

触摸声音是由config_soundEffectVolumeDb这个值控制的:范围是-6到0,代码如下:

void onPlaySoundEffect(int effect, int volume) {
        float volFloat;
        // use default if volume is not specified by caller
        if (volume < 0) {
            volFloat = (float) Math.pow(10, (float) mSfxAttenuationDb / 20);
        } else {
            volFloat = volume / 1000.0f;
        }
        //android.util.Log.d("hqb","volFloat==="+volFloat);
        Resource res = mResources.get(mEffects[effect]);
        if (mSoundPool != null && res.mSampleId != EFFECT_NOT_IN_SOUND_POOL && res.mLoaded) {
            mSoundPool.play(res.mSampleId, volFloat, volFloat, 0, 0, 1.0f);
        } else {
            MediaPlayer mediaPlayer = new MediaPlayer();

可以看出最大值应该是1.0f

但是即使调整到最大,其声音也是很细微

看网友有以下修改来增大音量:

diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index f00a910..3ee0c85 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1757,7 +1757,7 @@
     public static int[] DEFAULT_STREAM_VOLUME = new int[] {
         4,  // STREAM_VOICE_CALL
         7,  // STREAM_SYSTEM
-        5,  // STREAM_RING
+        7,  // STREAM_RING
         15, // STREAM_MUSIC
         6,  // STREAM_ALARM
         7,  // STREAM_NOTIFICATION
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 253b4e3..5733d8e 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -49,7 +49,7 @@
             *rightVolume != std::clamp(*rightVolume, 0.f, 1.f)) {
         ALOGI("volume l=%f r=%f out of (0.f, 1.f) bounds, using 1.f", *leftVolume, *rightVolume);
         // for backward compatibility use 1.f.
-        *leftVolume = *rightVolume = 1.f;
+        //*leftVolume = *rightVolume = 1.f;
     }
     return false;
 }
diff --git a/services/core/java/com/android/server/audio/SoundEffectsHelper.java b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
index 762f4d7..afd62c6 100644
--- a/services/core/java/com/android/server/audio/SoundEffectsHelper.java
+++ b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
@@ -248,7 +248,8 @@
 
         Resource res = mResources.get(mEffects[effect]);
         if (mSoundPool != null && res.mSampleId != EFFECT_NOT_IN_SOUND_POOL && res.mLoaded) {
-            mSoundPool.play(res.mSampleId, volFloat, volFloat, 0, 0, 1.0f);
+            // mSoundPool.play(res.mSampleId, volFloat, volFloat, 0, 0, 1.0f);
+            mSoundPool.play(res.mSampleId, volFloat*30, volFloat*30, 0, 0, 1.0f);
         } else {
             MediaPlayer mediaPlayer = new MediaPlayer();
             try {

实测可行

但到这里因为设备是不带电话功能的  所以ring的音量条被移除了  然而触摸声音默认就是跟着这个走的,所以我们还需要对其修改:

--- a/alps-mp-u0/frameworks/base/services/core/java/com/android/server/audio/SoundEffectsHelper.java
+++ b/alps-mp-u0/frameworks/base/services/core/java/com/android/server/audio/SoundEffectsHelper.java
@@ -190,8 +190,8 @@ class SoundEffectsHelper {
         mSoundPool = new SoundPool.Builder()
                 .setMaxStreams(NUM_SOUNDPOOL_CHANNELS)
                 .setAudioAttributes(new AudioAttributes.Builder()
-                        .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                        .setUsage(AudioAttributes.USAGE_MEDIA)
+                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                         .build())
                 .build();
         mPlayerAvailableCb.accept(mSoundPool);
@@ -265,7 +265,7 @@ class SoundEffectsHelper {

修改为AudioSystem.STREAM_MUSIC即可

至此  修改完成!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux | 进程优先级进程的环境变量

文章目录 进程概念4、进程优先级4.1基本概念4.2查看系统进程4.2.1 ps -l4.2.2 PRI & NI 4.3用top命令更改已存在进程的nice&#xff1a; 5、环境变量5.1常见环境变量5.2查看环境变量5.3测试PATH配置环境变量 5.4代码中获取环境变量5.4代码中获取环境变量 进程概念 4、进程…

RFID 智慧城市书房:开启智慧阅读新时代

在当今数字化、智能化的时代&#xff0c;人们对于阅读的需求和体验也在不断升级。RFID 智慧城市书房的出现&#xff0c;为满足人们对高品质阅读环境的追求提供了全新的途径。 一、RFID 技术&#xff1a;智慧城市书房的核心支撑 RFID&#xff0c;即射频识别技术&#xff0c;是一…

DDS IP实现啁啾信号

简介 DDS&#xff08;Direct Digital Synthesizer&#xff09;即数字合成器&#xff0c;是一种新型的频率合成技术&#xff0c;具有低成本、低功耗、高分辨率、频率转换时间短、相位连续性好等优点&#xff0c;对数字信号处理及其硬件实现有着很重要的作用。DDS 的基本…

18945 小团的配送团队

### 思路 1. **建图**&#xff1a;将订单视为图的节点&#xff0c;已知关系视为图的边&#xff0c;构建无向图。 2. **连通分量**&#xff1a;使用深度优先搜索&#xff08;DFS&#xff09;或广度优先搜索&#xff08;BFS&#xff09;找到图中的所有连通分量。 3. **排序**&…

探索人工智能的未来:埃里克·施密特2024斯坦福大学分享六

代理与文本生成模型的未来展望 您认为明年代理或文本生成模型会出现通货膨胀点吗&#xff1f; 不&#xff0c;不会。 我听到了类似的观点&#xff0c;尤其是埃里克科维茨的看法。他有一个很好的方式来阐述这三个趋势。虽然我之前也听说过这些趋势&#xff0c;但将它们整合起…

C语言破墙镐对称飞迷宫

目录 开头程序程序的流程图程序游玩的效果(gif)结尾 开头 大家好&#xff0c;我叫这是我58。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <Windows.h> enum WASD {W,A,S,D }; void printmaze(const char s…

【CTF Web】CTFShow cookie泄露 Writeup(cookie泄露+URL解码)

cookie泄露 10 cookie 只是一块饼干&#xff0c;不能存放任何隐私数据 解法 按 F12 打开开发者工具&#xff0c;点击网络&#xff0c;刷新页面。 flag 在 响应标头的 Set-Cookie 中。 用 URL 解码工具转换。 Flag ctfshow{8483acdb-a677-4c77-8aff-438d44ff1a3e}声明 本博客…

论文翻译软件哪个好用?如何将论文转化?

在学术海洋里遨游&#xff0c;每一篇论文都是思想的灯塔。 但当这座灯塔用外语构建&#xff0c;如何让它在中国读者面前同样熠熠生辉&#xff1f;别担心&#xff0c;把论文翻译成中文的旅程&#xff0c;不仅可以轻松启航&#xff0c;还能优雅靠岸&#xff01; 不知道怎么把论…

【Android笔记】Android APK编译打包流程

前言 本文将介绍Android从一个项目打包成APK的过程&#xff0c;其中涉及Android Java和Kotlin文件、资源文件、清单文件、依赖jar包和so库等在打包过程中处理。 步骤 总体的打包流程如下图&#xff0c;下面就介绍下详细的打包步骤。 1、将aidl文件编译成java文件 在构建过程中…

OpenAI API VBA function returns #Value! but MsgBox displays response

题意&#xff1a;“OpenAI API VBA 函数返回 #Value!&#xff0c;但 MsgBox 显示响应” 问题背景&#xff1a; I am trying to integrate the OpenAI API into Excel. The http request to OpenAI chat completion works correctly and the response is OK. When I display it…

esp32c3 luaos

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、介绍二、相关介绍2.1helloworld——2.2任务框架2.3消息传递 与消息订阅2.4uart2.5二进制数据/c结构体的打包与解析2.6 zbuffer库2.8 uart 485 数据解析2.9 …

Ubuntu 20.04安装中文输入法

本文旨在详细介绍在Ubuntu 20.04操作系统中安装中文输入法的步骤和方法。我们将从选择适合的中文输入法软件、下载与安装过程、配置输入法设置以及解决可能遇到的问题等方面展开讲解&#xff0c;帮助用户轻松实现在Ubuntu 20.04系统下流畅输入中文的需求。无论你是Ubuntu的新手…

东方银行--用 MinIO 和 Dremio 替代 Hadoop

我们的客户是一家总部位于日本的全球金融机构&#xff0c;最近与MinIO和Dremio一起完成了一个雄心勃勃的Hadoop替换项目。你可以在Subsurface的这个演讲中看到他们介绍它&#xff0c;但我们认为我们也会把它写下来。与大多数银行一样&#xff0c;该公司已经建立了大量的Hadoop足…

游戏开发设计模式之状态模式

目录 状态模式在Unity中的具体实现案例是什么&#xff1f; 如何在游戏开发中有效地结合状态模式与享元模式以优化资源使用&#xff1f; 状态模式与其他设计模式&#xff08;如观察者模式、策略模式&#xff09;结合使用的实际例子有哪些&#xff1f; 在处理复杂状态变化时&…

day19:生成器、yield表达式、三元表达式、生成式和函数的递归

一、生成器 1. 如何得到自定义的迭代器 【方法一】&#xff1a;在函数内一旦存在yield关键字&#xff0c;调用函数并不会执行函数体代码&#xff0c;会返回一个生成器对象&#xff0c;生成器即自定义的迭代器。 【方法二】&#xff1a;生成器表达式 反问&#xff1a;为什么自…

信息系统安全等级划分及其重要性:构建安全基石

在信息化社会&#xff0c;数据已成为企业与国家的重要资产&#xff0c;其安全防护日益受到重视。我国的“信息系统安全等级保护制度”正是在这一背景下应运而生&#xff0c;旨在通过等级划分&#xff0c;为不同级别的信息系统提供适配的安全保护措施&#xff0c;确保信息资产的…

Camera篇(一)ov13850调试

ov13850一千三百万像素&#xff0c;必须离线模式&#xff0c;所以ISP TDM配置离线 menuconfig 中需要将ISP TDM功能打开&#xff0c;同时开启WDR 配为&#xff08;*&#xff09; dts配置 work_mode 一律配1 &vind0 {csi_top <360000000>;csi_isp <322000000…

基于x86 平台opencv的图像采集和seetaface6的眼睛状态检测(睁眼,闭眼)功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.2 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的眼睛状态检测(睁眼,闭眼)功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的眼睛…

【C++ Primer Plus习题】3.4

问题: 解答: #include <iostream> using namespace std;const int DAY_TO_HOUR 24; const int HOUR_TO_MIN 60; const int MIN_TO_SEC 60;int main() {long seconds 0,record0;int days 0, hours 0, minutes0;cout << "请输入秒数:";cin >>…

进阶-5.锁

锁 1.概述2.全局锁3.表级锁3.1 介绍3.2 表锁3.3 元数据锁3.4意向锁 4.行级锁 1.概述 分类 按锁的粒度分类&#xff1a; 全局锁&#xff1a;锁住数据库中所有表表级锁&#xff1a;每次操作锁定整张表行级锁&#xff1a;每次操作锁定对应的行数据 2.全局锁 介绍 全局锁就是对…