软件测试 | 测试开发 | 使用 adb 对 Android 声音控制全面适配

429 阅读3分钟

在360开测平台中,线上的手机需要对音量进行一个控制,防止一些视频,音乐,游戏的 apk 发出的声音,影响办公环境,但是需要在360开测平台录制视频,音频脚本的需求来讲,我们不能直接控制静音,需要对 apk 进行一个合理的兼容,动态的去设置声音和检测声音。

在 android 开发中,我们可以使用 AudioManager 中调用 setStreamMute 和 getStreamVolume 两个方法来设置和获取当前的音量。但是在Android7.0 版本以上,我们需要动态的去申请免打扰的权限,也就是需要手工介入。

所需要的权限限制:

Manifest.permission.MODIFY_PHONE_STATE </code><code style='border-radius: 0px;white-space: pre;display: flex;font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;'>Manifest.permission.ACCESS_NOTIFICATION_POLICY

这些权限的限制,对脚本来说简直就是灾难。下面我们来看一下 28的源码:(注意我标红的地方, 以 setStreamVolume 源码为例)

我们翻看一下 AudioManager:

编辑切换为居中

添加图片注释,不超过 140 字(可选)

参数说明(下面说的参数都是这三个参数)</code>`int streamType  : 就是你设置设置音量的类型,是一个常量, 比如说 AudioManager.STREAM_MUSIC 就是说媒体音量。``int index  : 控制声音的大小,范围不同,有的范围是[0~15], 有的范围 [0~7], 设置的时候可以先查询一下。`<code>int flags  : 设置后有什么变化,比如说 FLAG_PLAY_SOUND 等等...

本质就是获取 IAudioServer 服务,然后调用了 setStreamVolume。

IAudioService

编辑切换为居中

添加图片注释,不超过 140 字(可选)

这个类是一个接口类,其中 setStreamVolume, 4个参数(参数越多,反射越困难,并且 u1 包是不包含 context 对象的)

AudioService

既然 IAudioService 是一个接口类,那么,必然有实现这个类的地方,要不然就属于无效代码了。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

一些权限控制和最终实现的地方。最终实现的还有另外一个方法,我就不粘贴了,网上基本都能找到。

到这里为止,就会发现,想反射调用难度有点大。那我们直接来看使用 adb 命令来控制声音音量。

在网上都可以找到

Android 10、11 adb 设置音量/修改具体项目的音量_小feifei的博客-CSDN博客_adb 音量

Android 10、11 adb 设置音量/修改具体项目的音量

这样一篇文章,这篇文章并不是只有 Android 10 才可以使用,它的使用范围是手机版本 >= 8.0 版本就可以使用了。

我们来看一下命令:

adb shell media volume --show --stream 3 --set 1</code>`--stream 后面跟 streamType 这个参数, int 类型`<code>--set 后面跟 index 这个参数的数值, int 类型

在手机版本 < 8.0 版本中,调用这个命令会出错,说没有 volume 这个服务,那低版本的怎么兼容呢?

5.1.0 版本

adb shell service call audio 4 i32 streamType i32 index i32 flags

i32 是int类型的整数,后面跟了设置声音的三个参数。

audio 是系统服务,我们可以执行

adb shell service list

来查看服务,看下图:

编辑切换为居中

添加图片注释,不超过 140 字(可选)

那后面跟着 4 怎么解释?

编辑切换为居中

添加图片注释,不超过 140 字(可选)

我们把 IAudioService 源码打开,看到 setStreamVolume 是第四个方法,是不是很清楚明白了。

那我们看一下怎么获取当前音量的值:

service call audio 13 i32 streamType

没看错,还是直接看 getStreamVolume 在第几个就可以了。

通过上面的逻辑,我们直接找源码,可以把Android 所有版本都可以这么做:

</code>`   /**``     * 设置声音``     * @param type``     * @param volume``     * @return``     */``    public String setAudioCMD(int type, int volume){``        String cmd  = "";``        if(Build.VERSION.SDK_INT == 22){``            cmd = String.format("service call audio 4 i32 %d i32 %d i32 0", type, volume);``        }else if(Build.VERSION.SDK_INT &gt;= 23 || Build.VERSION.SDK_INT &lt;= 25){``            cmd = String.format("service call audio 3 i32 %d i32 %d i32 0", type, volume);``        }else if(Build.VERSION.SDK_INT &gt;= 26) {``            cmd = String.format("media volume --show --stream %d --set %d", type, volume);``        }``        return cmd;`<code style='border-radius: 0px;white-space: pre;display: flex;font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;'>    }

/**</code>`     * 查看手机声音设置是否成功``     * @param type  2 手机铃声  3 手机媒体音量``     * @return``     */``    public String getAudioCMD(int type){``        String cmd  = "";``        if(Build.VERSION.SDK_INT == 22){``            cmd = String.format("service call audio 13 i32 %d", type);``        }else if(Build.VERSION.SDK_INT == 23){``            cmd = String.format("service call audio 9 i32 %d", type);``        }else if(Build.VERSION.SDK_INT == 24 || Build.VERSION.SDK_INT == 25){``            cmd = String.format("service call audio 8 i32 %d", type);``        }else if(Build.VERSION.SDK_INT &gt;= 26) {``            cmd = String.format("media volume --show --stream %d --get", type);``        }``        return cmd;`<code style='border-radius: 0px;white-space: pre;display: flex;font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;'>    }

我们最后来看一下最后的结果输出:

android 版本 &gt;= 8.0</code>` ``    [v] will control stream=2 (STREAM_RING)``    [v] will get volume``    [v] Connecting to AudioService``    [v] volume is 6 in range [0..15]``
``    当前声音是 6, 范围是 [0..15]``
``android 版本 &lt; 8.0``
``	Result: Parcel(00000000 00000009   '........')``	`<code style='border-radius: 0px;white-space: pre;display: flex;font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;'>	当前的声音是 900000009 是用16进制表示声音的。


更多学习资料戳!!!