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

有客户反馈: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即可

至此  修改完成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值