需求:将默认媒体音设置为最大,就是将STREAM_MUSIC对应的默认音量设置为最大。

frameworks/base/media/java/android/media/AudioSystem.java

    public static int[] DEFAULT_STREAM_VOLUME = new int[] {
        4,  // STREAM_VOICE_CALL
        7,  // STREAM_SYSTEM
        5,  // STREAM_RING
       // 5, // STREAM_MUSIC
       //修改如下
        15, // STREAM_MUSIC
        6,  // STREAM_ALARM
        5,  // STREAM_NOTIFICATION
        7,  // STREAM_BLUETOOTH_SCO
        7,  // STREAM_SYSTEM_ENFORCED
        5, // STREAM_DTMF
        5, // STREAM_TTS
        5, // STREAM_ACCESSIBILITY
    };

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

   /** Maximum volume index values for audio streams */
    protected static int[] MAX_STREAM_VOLUME = new int[] {
        5,  // STREAM_VOICE_CALL
        7,  // STREAM_SYSTEM
        7,  // STREAM_RING
        15, // STREAM_MUSIC
        7,  // STREAM_ALARM
        7,  // STREAM_NOTIFICATION
        15, // STREAM_BLUETOOTH_SCO
        7,  // STREAM_SYSTEM_ENFORCED
        15, // STREAM_DTMF
        15, // STREAM_TTS
        15  // STREAM_ACCESSIBILITY
    };

将默认值改为最大值15,发现并不生效。
frameworks/base/services/core/java/com/android/server/audio/AudioService.java

        int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
        if (defaultMusicVolume != -1 &&
                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
                defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
        } else {
            if (isPlatformTelevision()) {
                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
            } else {
                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
                        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
            }
        }

发现属性值的设置优先于数组的设置 。
直接在system/build.prop添加ro.config.media_vol_default=15,pull下来加好后再push,再恢复出厂设置就可以看有无生效,不用重编系统,会节省时间,验证有效。

结论:直接设置ro.config.media_vol_default就可以。

以上,可解决问题,下面是中间遇到的一些问题,读者可忽略,本人仅作记录。

-------------------分割线------------------

后续:其实有很多博客都说到了设置属性值,但是设置完15之后,发现settings中媒体音的进度条并没有更新,也就是没有滑到最大(因为我设置了最大15)。那么,继续看settings是怎么更新进度条的。

packages/apps/Settings/src/com/android/settings/notification/VolumeSeekBarPreference.java

    public void setStream(int stream) {
        mStream = stream;
        setMax(mAudioManager.getStreamMaxVolume(mStream));
        // Use getStreamMinVolumeInt for non-public stream type
        // eg: AudioManager.STREAM_BLUETOOTH_SCO
        setMin(mAudioManager.getStreamMinVolumeInt(mStream));
        setProgress(mAudioManager.getStreamVolume(mStream));
    }

发现有个进度条设置的,直接写死setProgress(15),发现还是没更新,证明进度条不是由settings控制更新的。那这个更新的值是怎么拿到的,一看是mAudioManager.getStreamVolume(mStream),发现这就是我们平时获取音量的方法啊,最后发现值都是保存在mIndexMap(AudioService里)中,还是没找到怎么更新进度条的,发现按音量+/-按键进度条有更新,代码走到了AudioService的adjustStreamVolume方法,进行了一些音量的设置(这部分可以参考文末的文章),最后调用了VolumeStreamState(很重要的一个类)的setIndex方法,setIndex方法的最后发送了一个设置音量的广播,并把音量的新旧值传了出去

private final Intent mVolumeChanged;
mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
        mStreamVolumeAlias[mStreamType]);
sendBroadcastToAll(mVolumeChanged);        

广播的接收在
frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java

@Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            boolean changed = false;
            if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
                final int stream = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                final int level = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
                final int oldLevel = intent
                        .getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
                if (D.BUG) Log.d(TAG, "onReceive VOLUME_CHANGED_ACTION stream=" + stream
                        + " level=" + level + " oldLevel=" + oldLevel);
                changed = updateStreamLevelW(stream, level);
            } 
            ....
            if (changed) {
                mCallbacks.onStateChanged(mState);
            }
        }

最后调用onStateChanged更新UI,所以settings音量的进度条竟然是在SystemUI更新的?目前代码就跟到了这里,但是问题还是没有解决。

然后同事也在帮我看这个问题,他找了其他android10的板子设置了一下默认值,发现设置属性值是有生效的,主要是这两个板子的固件当初都是同一份代码编出来的,后面随着客户需求的不同,代码才出现了不同,出问题的固件是和其他同事协同开发的,然后我看了一下其他同事的提交记录,嗯?发现有改动到AudioServices,然后把同事改动的代码回退,竟然就好了???这…文章结束。最后问题就这样解决了,虽然看AudioServices的过程很痛苦,但是还是有收获的,把设置音量的流程理了一遍。参考文章值得一看哦。最后感谢同事。

参考文章:
专题分纲目录 Android Framework 音频子系统
Android SystemUI 音量条VolumeDialogImpl更新
android音频系统(4):AudioService之音量管理

Android10 Frameworks专栏其他文章:
android10 隐藏投影
android10 隐藏SystemUI锁屏下的多用户图标
android10 禁止下拉状态栏
android10 动态添加和隐藏一级菜单

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐