
Android 10 Android音量调节
2024-01-06 / 龙之叶
前言
在手机和平板上面,我们实际上能调节的也就5个音量:
流类型 | 最大音量 | 音量 | 默认音量 | 含义 |
---|---|---|---|---|
STREAM_VOICE_CALL | 5 | 1 | 4 | 通话音量 |
STREAM_RING | 7 | 0 | 5 | 铃声,通知音量等 |
STREAM_MUSIC | 15 | 0 | 5 | 多媒体音量 |
STREAM_ALARM | 7 | 0 | 6 | 闹钟音量 |
STREAM_BLUETOOTH_SCO | 15 | 0 | 7 | 蓝牙音量 |
1 按键的处理流程
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
1 | // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, |
在这里,通过Binder获取到了AudioService的实例,调用AudioService的handleVolumeKey()方法。
1 | // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP, |
在handleVolumeKey()方法里面,调用了adjustSuggestedStreamVolume方法,参数含义如下:
按键类型 | Audio Service操作类型 | 含义 |
---|---|---|
KEYCODE_VOLUME_UP | AudioManager.ADJUST_RAISE | 音量减 |
KEYCODE_VOLUME_DOWN | AudioManager.ADJUST_LOWER | 音量加 |
KEYCODE_VOLUME_MUTE | AudioManager.ADJUST_TOGGLE_MUTE | 改变静音状态 |
在按键的处理过程中,并没有将相应的code传递给AudioService,而是使用了相关的定义,将KEYCODE_VOLUME_UP等操作转化为了ADJUST_RAISE等。而flag存储了一些对音量的要求或者信息。
frameworks/base/media/java/android/media/AudioManager.java
1 | /** |
2 adjustSuggestedStreamVolume
接下来就到了AudioService的adjustSuggestedStreamVolume方法里面了:
1 | private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, |
这里需要注意的有以下几点:
- mUserSelectedVolumeControlStream:这个属性表示,用户是否已通过单击音量进度条选择音量流来更改由音量键控制的音量,如果mVolumeControlStream为-1,那么mUserSelectedVolumeControlStream 为false。说简单点,当用户点击了某个音量条,这时再去按下音量加减,这个时候调节的是你点击的那个流类型。
- getActiveStreamType:获取我们要控制的流的类型,当然,只是可能需要控制的流类型,还需要进一步确认。
- mStreamVolumeAlias[streamType]:进行流映射,获取最终需要调整的流类型
- suppressAdjustment:字面意思为抑制调整,为什么抑制调整呢,说白了,当我们没有显示音量的UI进度条的时候,不管我们是加音量还是减音量(注意:静音和解静音除外),这个时候都是先显示音量条,而不去改变音量的大小。所以当这个方法返回true的时候, direction = 0,这里direction为0就表示我们的操作为ADJUST_SAME,大家可以在AudioManager里面查看ADJUST_SAME的注释就知道这个操作表示只弹出UI但是不调整音量大小。
- adjustStreamVolume:进行音量的调整
3 adjustStreamVolume
进入到了adjustStreamVolume函数,该函数比较长,得分片段分析。
1 | private void adjustStreamVolume(int streamType, int direction, int flags, |
- mUseFixedVolume:表示使用固定音量,我们无法修改音量
- mStreamVolumeAlias[streamType]:进行音频流的映射,拿到映射后的音频流
- mStreamStates[streamTypeAlias]:mStreamStates是一个存储VolumeStreamState类型的数组,保存着每个音频流的状态。VolumeStreamState是AudioService的一个内部类,里面保存单个音频流的所有信息,比如流类型,音量大小,mute状态等。并且相同的流类型,在不同的设备,大小也是不一样的(比如耳机和扬声器,媒体音量大小是不一样的),这也是在VolumeStreamState里面去维护的。)
1 | private void adjustStreamVolume(int streamType, int direction, int flags, |
- getDeviceForStream:通过流类型去获取设备类型这里去获取设备类型,通过流类型获取到了对应的VolumeStreamState的实例,然后调用了其observeDevicesForStream_syncVSS方法去获取devices,在observeDevicesForStream_syncVSS方法里面,又会去调用AudioSystem的getDevicesForStream去获取设备,这是个native方法。
1 | private void adjustStreamVolume(int streamType, int direction, int flags, |
- 固定音量设备的处理
- 音量步进的处理:rescaleIndex方法,将音量值的步进量从源流类型变换到目标流类型下,由于不同的流类型的音量调节范围不同,所以这个转换是必需的。计算按下音量键的音量步进值。这个步进值是10而不是1。在VolumeStreamState中保存的音量值是其实际值的10倍,这是为了在不同流类型之间进行音量转化时能够保证一定精度的一种实现。可以理解为在转化过程中保留了小数点后一位的精度。
- 情景模式处理:情景模式的处理就涉及到了音量的调整,以及情景模式的切换,在切换情景模式(震动到响铃除外)的时候,是没有去调整音量的。通过adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0这一句体现出来的。
- 勿扰模式处理:
1 | private void adjustStreamVolume(int streamType, int direction, int flags, |
本文链接:
http://longzhiye.top/2024/01/06/2024-01-06/