当前位置: 首页 > news >正文

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

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

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

 @Overridepublic 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.ExportedPropertypublic 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.Stubimplements AccessibilityManager.TouchExplorationStateChangeListener,AccessibilityManager.AccessibilityServicesStateChangeListener,AudioSystemAdapter.OnRoutingUpdatedListener,AudioSystemAdapter.OnVolRangeInitRequestListener {private SoundEffectsHelper mSfxHelper;/** Handles internal volume messages in separate volume thread. */private class AudioHandler extends Handler {@Overridepublic 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 {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_PLAY_EFFECT:final int effect = msg.arg1, volume = msg.arg2;onLoadSoundEffects(new OnEffectsLoadCompleteHandler() {@Overridepublic 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@Overridepublic void run(boolean success) {mSoundPoolLoader = null;if (!success) {Log.w(TAG, "onLoadSoundEffects(), Error while loading samples");onUnloadSoundEffects();}}});mSoundPoolLoader.addHandler(onComplete); //增加onComplete Handlerint 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 callerif (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_CALL7,  // STREAM_SYSTEM
-        5,  // STREAM_RING
+        7,  // STREAM_RING15, // STREAM_MUSIC6,  // STREAM_ALARM7,  // 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.mrgr.cn/news/12457.html

相关文章:

  • 调试JS代码
  • 工厂模式和策略模式的区别
  • [Algorithm][综合训练][kotori和气球][体操队形][二叉树中的最大路径和]详细讲解
  • 本专业不好找工作,也许可以试试嵌入式 嵌入式学习路线 从C语言到MCU开发
  • 数据结构:顺序表
  • SpringCloud整合Nacos
  • [图论]游戏
  • 《陈天奇:机器学习科研的十年》阅读笔记
  • 金融基础知识-银行间债券市场交易规则+场外市场交易规则
  • 云计算day32
  • 力扣面试150 插入区间 模拟
  • 【Java项目开发】点菜系统(无前端)
  • 【扩散模型(八)】Stable Diffusion 3 diffusers 源码详解2 - DiT 与 MMDiT 相关代码(下)
  • 重卡智能充电机器人
  • while
  • windows11 开发环境资源整理
  • 命令模式详解
  • PPT布局图片文本解析检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]
  • 智慧升级,触手可及:Vatee万腾平台的全方位服务
  • 国内使用tensorflow_datasets加载数据