这是我假期练手小项目——钢琴块2(别踩白块儿2)自动程序——的前置科技树,主要是为了实现对屏幕的抓取和点击操作。
测试平台为win10 x64 1709 + VS2013 + python3.6.2,安卓设备分别为雷电模拟器(android 5.1.1),Total Control(远程桌面)和Mi 5s(android 7.0 ,MIUI 9.1.3.0)。
如果曾经安装过android studio或者android 模拟器,那么在其程序目录下就能够找到对应的文件:
adb.exe |
adb主程序 |
AdbWinApi.dll |
window下的api接口 |
AdbWinUsbApi.dll |
windows下的usb驱动接口 |
1. shift+右键-复制文件路径,随后复制全路径进入控制台
C:\Users\yyx11>"C:\Changzhi\dnplayer2\adb.exe" devices
List of devices attached
emulator-5554 device
5c04073c device
2. 添加adb目录到系统环境变量Path,控制台直接输入adb
C:\Users\yyx11>adb devices
List of devices attached
emulator-5554 device
5c04073c device
3. 将adb和对应的两个dll复制进入C:\Windows\System32(32位系统)或C:\Windows\SysWOW64(64位系统),控制台直接输入adb
如果不想每次都输入adb shell xxxxx,只需要直接输入adb shell,随后每次输入任何命令都相当于前面带有了adb shell:
C:\Users\yyx11>adb shell
root@x86:/ # dumpsys cpuinfo
退出时,输入exit即可。
调用adb shell发生如下错误时
error: device unauthorized. Please check the confirmation dialog on your device.
则进入设置->辅助功能->开发者模式->撤销usb调试授权,重新打开开发者模式即可。
手机/模拟器需要打开USB调试选项,并允许模拟点击(通常会弹出好几次窗口要求确认)。可参考百度:
安卓手机如何打开“开发者选项”?
https://jingyan.baidu.com/article/4dc40848bd6dd1c8d846f17e.html?st=2&os=0&bd_page_type=1&net_type=1
建议除了打开开发者模式外,另外勾选几个选项,可以大大提升效率(我的系统是android8的MIUI9):
选项 |
说明 |
不锁定屏幕 |
充电时屏幕不会休眠 |
显示点按操作反馈 |
显示点按操作的视觉反馈 |
指针位置 |
屏幕叠加层显示当前触摸点坐标 |
|
|
当系统中同时连接了多个安卓设备,则需要进行选择。
1. 首先,使用adb devices 获取所有的序列号。
C:\Users\yyx11>adb devices
List of devices attached
emulator-5554 device
5c04073c device
上面的是我的模拟器,下面的是手机。
2. 选择自己想要操作的设备,以后通过adb -s
C:\Users\yyx11>adb -s emulator-5554 shell dumpsys cpuinfo
或直接进入shell模式,之后则无需填写序列号
C:\Users\yyx11>adb -s emulator-5554 shell
root@x86:/ # dumpstats cpuinfo
其它常用命令,可以参考:
Android adb你真的会用吗?
https://www.jianshu.com/p/5980c8c282ef
截屏主要是使用screencap和pull命令。
screencap是截屏命令,指令说明如下:
screencap: invalid option -- v
usage: screencap [-hp] [-d display-id][FILENAME]
-h: this message
-p: save the file as a png. #保存为png
-d: specify the display id to capture, default 0. #截屏的显示器
If FILENAME ends with .png it will be savedas a png. #文件名以.png结尾则保存为png
If FILENAME is not given, the results willbe printed to stdout. #文件名未给出,则输出为stdout
通常情况下,千万不要不给文件名输出到stdout,不然你就得等待控制台不停地刷好几分钟的空格了2333 。
但是,adb不能直接截屏到电脑上,必须先截屏保存到android本地,然后使用pull命令拉取,否则会出现错误。
C:\Users\yyx11>adb shell screencap -p e:\1.png
Error opening file: e:\1.png (Read-only file system)
正确的做法如下:
#以下是截屏为screen.png并保存到系统的 /sdcard/下
C:\Users\yyx11>adb -s emulator-5554 shell screencap /sdcard/screen.png
#以下是将截屏保存到电脑的C:\Users\yyx11\1.png
C:\Users\yyx11>adb -s emulator-5554 pull /sdcard/screen.png 1.png
1831 KB/s (119524 bytes in 0.063s)
这样,截屏一次至少需要约1000ms时间,速度非常慢。
从整个流程中可以看出,adb先保存到了本地,而后发送给了电脑,电脑再从硬盘上读取出来显示。其中经历了2次写文件,1次读文件,1次编码,1次解码,1次USB传输,实在是太过复杂,尤其是读写文件和传输应该是主要瓶颈。但是找了很久,找不到提高adb速度的方法。大概adb为了兼容性考虑,本来也不求多高的实时率。
adb方法虽然简单通用,但是效率过低,后文中会介绍相对高速的方法。
模拟点击主要是使用adb shell input 命令。
input
Usage: input [
通常,只需要用到tap和swipe两个命令。
tap是单击命令:
tap (Default: touchscreen)
x是横坐标,y是纵坐标(左上角为原点,水平向右x增加,垂直向下y增加)
示例:
input tap 100 100 #点击屏幕坐标(100,100)
swipe是滑动命令
swipe [duration(ms)](Default: touchscreen)
x1是起点横坐标,y1是起点纵坐标,x2是终点横坐标,y2是终点纵坐标。duration是持续的毫秒数。
示例如下:
root@x86:/ # input swipe 200 200 300 300 500
input swipe 200 200 300 300 500
这两个命令没啥好说的,同样的优缺点:
简单、通用性强
速度太慢
要注意的有几点:
1. 点击事件对应的event在不同设备上不同,需要自己分析。
2. getevent监听得到的数据是十六进制,而sendevent需要十进制。
3. 因为有多条sendevent,所以点击速度比input还要慢得多