【Android】Android系统音量调节策略学习总结

前言

文章就Android平台主机接不同的外放设备时的音量调节策略做简要介绍。

一、主机版本

主机版本
RK3399广告屏Android7
Skyworth平板Android9
Skyworth车机Android9

二、外设类型

  • USB音箱底座
  • 蓝牙音箱
  • 3.5mm线控耳机

三、相关术语

  • track volume: 单个App设置音量时设置的是这个,它只影响本App的音量。
  • stream volume: 设置某一stream的音量,Android系统中支持的stream,可以在audio.h中找到。
  • stream volume alias: 设置的是同一组stream的音量,比如使用某个音量调节滑动条设置的音量。比如设置媒体音,所有App的媒体音都受到影响(但是电话音,闹钟音不受影响)。
  • master volume: 设置它等于设置所有的stream volume和track volume。它可以写到声卡里面去,控制所有声音的音量。也可以不写到声卡里面去,而是作为一个乘数因子来影响所有的音量。

四、音量调节流程

Android平台的设备,常见的手机、平板、车机、广告屏,调节音量基本有两种常用方式:音量键和滑动条。下面分别介绍写这两种方式的大致流程。

1.音量键

  1. 音量键的动作由 PhoneFallbackEventHandler 处理,它会调用AudioService.adjustSuggestedStreamVolume 调整“推荐的流”的音量。
  2. 获取“推荐的流”:stream = getActiveStreamType(…),就是获取当前活动的流。比如当前在通话,按音量键时,调节的就是话音的音量。
  3. 设置流的音量:adjustStreamVolume调用 sendMsg 发送 MSG_SET_DEVICE_VOLUME 消息,由handleMessage 来进行处理。
  4. 将设置后的StreamVolume保存到SettingsProvider中。

2.滑动条(SeekBar)

  1. 每一个SeekBar要绑定一个 SeekBarChangeListener 用来监听变化。

  2. 当SeekBar被滑动时,它的onProgressRefresh被调用,该函数会调用mOnSeekBarChangeListener.onProgressChanged 去调节设备音量。

  3. 每一个SeekBar对应一个stream,滑动SeekBar时会设置该stream的音量,也会去设置同属一个alias(同一分组)的其他stream的音量,伪代码如下:

    if(mStreamVolumeAlias[other stream] == stream)      
    	setvolume forother stream;
    
  4. 设置StreamVolume:adjustStreamVolume调用sendMsg 发送 MSG_SET_DEVICE_VOLUME
    消息,由 handleMessage 来进行处理。

  5. 将设置后的StreamVolume保存到SettingsProvider中。

能够看出按键调节和滑动音量条调节,最后的处理是一样的。最后都会保存到SettingsProvider中,可以用 adb shell settings get system volume_music_speaker 查看stream volume的值。

五、外设音量调节

当Android主机连接外放设备时,主要关心的是两者的音量同步问题。下面分别介绍几种常用的外接播放设备。

1.USB音箱、USB底座

此类设备,主机端的音量和设备端音量相互独立。
一般来说设备侧调节的是自身的功放参数,比如增益;主机端调节的是自身的输出音量,不会影响设备端音量。

2.蓝牙音箱、蓝牙耳机

  • 主机端连接蓝牙设备,涉及到一个“蓝牙绝对音量”的开关。该开关决定了主机端调节音量时是否同步调节设备端。
  • 当主机端开启了绝对音量:主机端音量调节会同步调节设备端;
  • 当主机端未开启绝对音量:主机端音量调节不会同步调节设备端,设备端独立调节;
  • 不管是否开启绝对音量,蓝牙设备端都不会反向同步音量变化给主机端。

3.3.5mm线控耳机

  • 对于普通的线控耳机,调节音量的原理是:主机端会监测耳机按下音量+/-键时的阻抗变化,触发相应的音量调节动作。
  • 实测发现,并不是所有的Android机型都会监测耳机的音量按键,比如RK3399的广告屏,插上3.5mm线控耳机,按耳机的音量键, 并不会触发音量调节;拿一部vivo手机测试,耳机可以控制手机音量。
  • 总之要看主机端是否有监控耳机动作的处理操作。

六、“静音”

这里的“静音”不同于通过按音量键或者拉动音量条逐级的调节为静音状态,而是指设备的“MUTE”状态。对应的操作为:

audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_MUTE, 1);

  关于“静音”,分析下常见的一个问题:当主机端“静音”后,连接其它外放设备,再断开连接,主机端会自动变为“非静音”状态。 前面说了音量调节的一般流程,简化来说就两步:

  第一步:设置StreamVolume;
  第二步:保存到SettingsProvider;

  当设置“静音”时,设备只执行第一步,不会执行第二步;
  当连接外放设备时,系统监测到外放设备connected,会触发一次“UNMUTE”动作,同样是只执行第一步,不执行第二步。因为静音时未保存SettingsProvider,所以“UNMUTE”后的StreamVolume还是静音前的值。

七、常用命令

  1. 查看系统有哪些volume,以"volume_"开头的是音量相关的

    adb shel settings list system
    
  2. 查看某一个volume的值,以volume_music_speaker为例

    adb shell settings get system volume_music_speaker
    
  3. 使用media命令设置音量,会保存到SettingsProvider中

    adb shell media volume --stream 3 --get         // 获取音量
    adb shell media volume --stream 3 --adj lower   // 降低音量
    adb shell media volume --stream 3 --set 0       // 设置音量为0
    
  4. 使用keyevent设置音量,不会保存到SettingsProvider中

    adb shell input keyevent 164					// mute,不同平台键值可能有差异。
    
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值