写点什么

使用 adb 对 Android 声音控制全面适配

  • 2022 年 9 月 16 日
    北京
  • 本文字数:2424 字

    阅读完需:约 8 分钟

在 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:


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

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

IAudioService

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

AudioService

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

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

到这里为止,就会发现,想反射调用难度有点大。那我们直接来看使用 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
复制代码

来查看服务,看下图:

那后面跟着 4 怎么解释?

我们把 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;'>	当前的声音是 9 , 00000009 是用16进制表示声音的。
复制代码

更多学习资料戳!!!

https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=infoQ&timestamp=1662366626&author=xueqi

用户头像

社区:ceshiren.com 2022.08.29 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料、实事更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬

评论

发布
暂无评论
使用 adb 对 Android 声音控制全面适配_测试_测吧(北京)科技有限公司_InfoQ写作社区