AudioManager中setStreamVolume与adjustStreamVolume
来源:互联网 发布:相机数据恢复 编辑:程序博客网 时间:2024/06/03 08:00
今日遇到一个bug, 酷狗音乐扬声器播放歌曲,此时假定音量值为10。
插入耳机,按手机音量键将音量值调为0,拔出耳机,播放音乐,发现扬声器音量也被置为0。
一、亲自验证?
- 只有当音量值调为0时,耳机与扬声器音量会将另一方置0,其他音量时互不影响
- 目前QQ音乐、网易云均无此现象
二、查看系统volume日志,惊奇发现:
AudioService: setStreamVolume 3, index = 0, flags = 8 from pid = 23805 callingPackage = com.kugou.androidAudioService: update volume cache, stream:3, device:headphone, index:0, caller:com.kugou.androidAudioService: update volume cache, stream:9, device:headphone, index:0, caller:com.kugou.androidActivityManager: Broadcast: Intent { act=android.media.VOLUME_CHANGED_ACTION flg=0x14000010 (has extras) } ordered=false userid=-1 callerApp=ProcessRecord{3f82fa1 994:system/1000}AudioService: update volume cache, stream:9, device:speaker, index:0, caller:com.kugou.androidActivityManager: Broadcast: Intent { act=android.media.VOLUME_CHANGED_ACTION flg=0x14000010 (has extras) } ordered=false userid=-1 callerApp=ProcessRecord{3f82fa1 994:system/1000}ActivityManager: Broadcast: Intent { act=android.media.VOLUME_CHANGED_ACTION flg=0x14000010 (has extras) } ordered=false userid=-1 callerApp=ProcessRecord{3f82fa1 994:system/1000}AudioService: applyDeviceVolume_syncVSS stream: 3, device: 8, index: 0AudioService: applyDeviceVolume_syncVSS stream: 9, device: 2, index: 0AudioService: sendVolumeUpdate: StreamType = 3, oldIndex = 1, newIndex = 0com.kugou.android D/setVolume: set:0AudioService: applyAllVolumes stream: 3, device: 2, index: 0AudioService: applyAllVolumes stream: 3, device: 4, index: 0AudioService: applyAllVolumes stream: 3, device: 8, index: 0AudioService: applyAllVolumes stream: 3, device: 128, index: 0AudioService: applyAllVolumes stream: 9, device: 2, index: 0AudioService: applyAllVolumes stream: 9, device: 4, index: 7AudioService: applyAllVolumes stream: 9, device: 8, index: 0AudioService: applyAllVolumes stream: 9, device: 128, index: 8AudioService: adjustSuggestedStreamVolume() stream=3, flags=4116, caller=MediaSessionServiceAudioService: adjustStreamVolume() stream =3, dir =0, flags =4112, callingPackage =android, Pid = 994AudioService: sendVolumeUpdate: StreamType = 3, oldIndex = 0, newIndex = 0om.kugou.android D/MediaSessionHelper: dispatched volume adjustment
- stream: 3 表示音频流音量
- stream: 9 表示文本识别音(暂无使用)
- device: 2 表示 DEVICE_OUT_SPEAKER 扬声器
- device: 4 表示 DEVICE_OUT_WIRED_HEADSET 线控耳机
- device: 8 表示 DEVICE_OUT_WIRED_HEADPHONE 普通耳机
- device: 128 表示 DEVICE_OUT_BLUETOOTH_A2DP 蓝牙A2DP输出
当音量设置为0时,竟然将这几个设备音量均设置为0。
三、对比网易云音乐
1. 日志区别
AudioService: adjustSuggestedStreamVolume() stream=3, flags=4113, caller=MediaSessionServiceAudioService: adjustStreamVolume() stream =3, dir =-1, flags =4113, callingPackage =android, Pid = 980AudioService: update volume cache, stream:3, device:headphone, index:70, caller:MediaSessionService
2. 初步结论
网易云使用的是adjustStreamVolume,酷狗使用的是setStreamVolume.
将代码改为adjustStreamVolume发现解决了问题。
setStreamVolume:直接设置音量大小
adjustStreamVolume :设置direction,以步长调节音量大小
四、根本原因:源码
1. 日志区别
AudioManager的setStreamVolume进入AudioService之后,有这么一段if (!checkSafeMediaVolume(streamTypeAlias, index, device)) { //音量安全检测 mVolumeController.postDisplaySafeVolumeWarning(flags); mPendingVolumeCommand = new StreamVolumeCommand( streamType, index, flags, device);} else { onSetStreamVolume(streamType, index, flags, device); //重点 index = mStreamStates[streamType].getIndex(device);}private void onSetStreamVolume(int streamType, int index, int flags, int device) { setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false); // setting volume on master stream type also controls silent mode if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || (mStreamVolumeAlias[streamType] == getMasterStreamType())) { int newRingerMode; if (index == 0) { //如果设置音量为0,设置新的铃声模式:震动、静音、有声 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE : VOLUME_SETS_RINGER_MODE_SILENT ? AudioManager.RINGER_MODE_SILENT : AudioManager.RINGER_MODE_NORMAL; } else { newRingerMode = AudioManager.RINGER_MODE_NORMAL; } setRingerMode(newRingerMode, TAG + ".onSetStreamVolume", false /*external*/); }}setRingerMode这个里面会调用setRingerModeInt,这个里面会将0-9的StreamType中符合静音的type设置mStreamStates[streamType].mute(null, false),接着handler.mute_syncVSS(state);然后发送消息if (updateVolume) { sendMsg(mAudioHandler, MSG_SET_ALL_VOLUMES, SENDMSG_QUEUE, 0, 0, VolumeStreamState.this, 0);}接着将一些applyAllVolumes执行jni方法音量置0。
还请以后注意这个问题,使用合理的设置音量方式。
正确使用方式为:
如果想把音量设置为0,先用setStreamVolume设置1,再用adjustStreamVolume设置0。
阅读全文
0 0
- AudioManager中setStreamVolume与adjustStreamVolume
- AudioManager
- AudioManager
- AudioManager
- AudioManager
- Android音量控制-AudioManager与来电振动
- Android中AudioManager和MediaRecorder讲解
- 【AudioManager】AudioManager 详解
- 黑名单来电自动静音(PhoneStateListener与AudioManager)
- Android中AudioManager 音量的类的方法
- Android AudioManager
- AudioManager学习
- AudioManager简述
- AudioManager详解
- AudioManager使用方法
- AudioManager详解
- 浅谈AudioManager
- AudioManager简介
- <NOIP> 13 . P1046 陶陶摘苹果
- Mybatis的数据源 DataSource
- Spark streaming 跟踪kafka offset的问题研究
- mysql 本地ip访问无法连接ERROR 1045 (28000)
- keras入门实战:手写数字识别
- AudioManager中setStreamVolume与adjustStreamVolume
- MySQL workbench外网通过PuTTY设置SSH的tunnels远程访问内网服务器中的MySQL
- Stringstr=new String("abc") 这行代码究竟创建了几个对象?
- 2017.06.30—Visio Studio下MFC c++的入口程序(main函数)
- java构造器的调用顺序
- Linux下静态链接库与动态链接库的区别
- C++代码中extern "C"作用
- 服务框架
- 最短路径算法——Dijkstra算法