跳转至

安卓自动化库

目前 hyuiauto 库可以自动化 安卓设备

hyuiauto 通过 adb 来连接控制 安卓设备。

hyuiauto 和设备的连接架构图如下


AndroidConnector

hyuiauto 通过 AndroidConnector来 连接 设备

ac = AndroidConnector()

有2个参数,分别是本机 adb server 的 地址和端口,通常不需要指定,使用缺省值即可

host : adb server 地址,缺省值为 127.0.0.1

port : adb server 端口,缺省值为 5037


hyuiauto 内置了 Windows 的 adb 程序,如果是Windows系统不需要你额外安装。

实例化 AndroidConnector时,如果发现没有 adb 服务,会自动启动adb 服务。

根据条件选中设备

调用 device 方法,可以根据过滤条件,选中某个连接在本机上所以安卓设备,

返回该安卓设备对应的 AndroidDevice 对象

参数为:

  • manufacturer 制造商名称

缺省值为 None, 表示不限制这个条件

  • model 设备型号

缺省值为 None, 表示不限制这个条件

  • sn 设备序列号

缺省值为 None, 表示不限制这个条件

  • installInputApk 是否安装支持自动化的输入法

缺省值为 True, 表示自动在设备上安装输入法 ADBKeyboard.apk 应用。

这个应用用来支持自动化输入中文等特殊字符的。

from hyuiauto import AndroidConnector

ac = AndroidConnector()
devices = ac.device(
    manufacturer='samsung', 
    model='SM-N9700', 
    sn='R58M82VN5GE')


如果 manufacturer,model,sn 这3个条件都没有限制, 选中第一个找到的安卓设备

获取所有安卓设备

调用 devices 方法可以获取连接在本机上所有安卓设备,

from hyuiauto import AndroidConnector

ac = AndroidConnector()
devices = ac.devices()
print(devices)

返回值是一个列表,里面每个元素分别为 对应一个安卓设备的 AndroidDevice 类型的对象

获取第一个安卓设备

调用 firstDevice 方法可以获取连接在本机上的第一个安卓设备对的 AndroidDevice 类型的对象

参数为:

  • installInputApk 是否安装支持自动化的输入法

缺省值为 True, 表示自动在设备上安装输入法 ADBKeyboard.apk 应用。

这个应用用来支持自动化输入中文等特殊字符的。

from hyuiauto import AndroidConnector

ac = AndroidConnector()
device = ac.firstDevice()

AndroidDevice

每个AndroidDevice 类型的对象,对应一个连接到本电脑的安卓设备

它的方法可以对该设备进行信息的获取和控制。

执行 adb shell 命令

shell 方法可以执行adb shell命令。

参数为 要执行的 shell 命令

返回 字符串 包含 命令输出的文本内容

比如

device.shell('pm list packages')

安装 apk

install 方法可以 安装指定的apk。

参数为 要安装的apk 在本电脑的路径

返回值为 字符串,是包含 命令输出的文本内容

比如

device.install('d:\ADBKeyboard.apk')

打开 app

openApp 方法可以 打开某个应用。

参数为 要打开的应用 的 package 名称

返回值为 字符串,是包含 命令输出的文本内容

比如

device.openApp('com.tencent.mm')


怎么知道要打开应用的 package 名称呢?

在手机上打开app,连接好电脑,

然后直接运行命令行

python -c "from hyuiauto import *;runAndroidTool()"

会打开一个浏览器界面,先点击 列出安卓设备

出现连接电脑的安卓设备后,点击 显示当前的Package


或者运行如下命令,直接在命令行窗口看到当前的app包名

python -c "from hyuiauto import *;showCurrentAppPackageName()"

会输出类似如下结果

package  : com.tencent.mm
activity : .ui.LauncherUI

分别对应当前打开应用的 package 名 和 activity名


具体操作见视频讲解

根据坐标点击屏幕

tap 方法可以 点击屏幕某个位置。

参数为 要点击位置的坐标 x, y 坐标

比如

# 点击屏幕坐标 (100,300) 位置
device.tap(100,300)


怎么知道安卓设备要点击位置的坐标呢? 点击参考这个视频

根据坐标长按屏幕

longPress 方法可以 长按屏幕某个位置。

参数为 要长按位置的坐标 x, y 坐标

比如

# 长按屏幕坐标 (100,300) 位置
device.longPress(100,300)

根据坐标滑动屏幕

swipe 方法可以 在屏幕上滑动操作。

参数为 滑动起始 和 终止位置的 x, y 坐标, 还有滑动的时长

比如

# 从 (600,1000) 滑动到  (600,1800), 耗时 800 毫秒
device.swipe(600,1000,600,1800, 800)

返回

goBack 方法实现点击安卓返回键的功能。

比如

device.goBack()

截屏

screenCap 方法可以 将当前屏幕内容进行截屏。

返回值为截屏对应的png格式字节内容。

比如

scrPng = device.screenCap()
with open('tmp.png','wb') as f:
    f.write(scrPng)

输入字符串

如果要输入的只是英文字符串,并且中间没有空格之类的特殊字符, 可以使用 shell 方法, input 子命令, 如下

info = 'byhy'
device.shell(f'input text "{info}"')


如果有空格就会比较麻烦,需要用 %s 替换,比如

info = 'byhy%spython'
device.shell(f'input text "{info}"')

而且没法支持中文


如果要支持中文和任何特殊字符, 可以使用 inputString 方法。

inputString 方法需要预先在安卓设备上安装好输入法apk ADBKeyboard.apk


如下

info = '白月黑羽 你好!'
device.inputString(info)


参数为

inStr : 要输入的字符串内容

endWithOK : 输入完成后,是否确认,缺省为 False 表示

屏幕文字获取-返回信息列表

screenToTexts 方法可以 把屏幕上所有的文字按识别组,依次存放到一个列表中。

识别文本结构次序为 屏幕 按行从上到下,每行从左到右

参数为

  • range : 识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只识别该范围内的文字内容


比如

items = device.screenToTexts(range=(0, 514, 1065, 2103))
print(items)


返回结果格式如下

[ 
    [ 
        ([747.0, 796.0], [1020.0, 841.0]),  
        ('表格', 0.9990993738174438)
    ],
    [ 
        ([747.0, 796.0], [1020.0, 841.0]),
        ('取消', 0.9738937616348267)
    ]
]

最外层列表里面,每个元素为识别的 一条文本内容

每条文本对应的又是一个列表, 第一个元素为 文本框坐标 ,第二个元素为 文本内容

文本框坐标 又是一个列表,里面依次为 左上角,右下角 的xy坐标

文本内容 又是一个列表,里面依次为 文本字符串识别可靠度 , 识别可靠度 最高为 1,最小为0, 值越大越可靠


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR

屏幕文字获取-返回字符串

screenToText 方法可以 把屏幕上所有的文字保存到一个字符串中返回。

屏幕识别的各条字符串内容中用 换行符 隔开

参数为

  • range : 识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只识别该范围内的文字内容


比如

txt = device.screenToText()

结果格式如下

6:14 
    81%
设置
计算器
京东
支付宝
網易
相册
网易新闻
哗哩哗哩
相机
微信


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR

获取屏幕上文字的坐标

textPosOnScreen 方法可以 获取屏幕某个文本所在的位置坐标。

参数为

  • text : 要识别的目标文本内容

  • exact : 是否完全匹配

缺省为 True , 表示必须完全和 text参数匹配,

如果为 False ,表示只需包含text参数内容即为识别目标

  • range : 识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只在该范围内,搜寻目标文字

  • timeout : 超时时长,缺省值为10秒

如果在指定时长内没有在屏幕上找到目标文字,抛出 RuntimeError 错误

  • ocrRet : 前面已经获取的OCR识别结果,缺省为 None

如果在指定时长内没有在屏幕上找到目标文字,抛出 RuntimeError 错误

否则,返回值为一个元组,内容是该文本在屏幕的 左上角xy坐标 和 右下角xy坐标


比如

pos = device.textPosOnScreen('小程序')
print(pos)

结果为 格式如下:

(878.0, 1791.0, 959.0, 1838.0)


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR

点击屏幕上的文字

tapTextOnScreen 方法可以 点击屏幕某个文本。如果有多个匹配,点击第一个找到的

参数为

  • text : 要点击的目标文本内容

  • exact : 是否完全匹配

缺省为 True , 表示必须完全和 text参数匹配,

如果为 False ,表示只需包含text参数内容即为点击目标

  • range : 目标文字的识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只在该范围内,搜寻目标文字

  • timeout : 超时时长,缺省值为10秒

如果在指定时长内没有在屏幕上找到目标文字,抛出 RuntimeError 错误

  • holdTime : 点按时长,缺省为0表示普通快速点击

如果为其它整数,则表示点击并且按住的时长,可以模拟长按动作

  • ocrRet : 前面已经获取的OCR识别结果,缺省为 None


比如

pos = device.tapTextOnScreen('搜索职位、公司', exact=False) 


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR

等待屏幕上指定文字出现

waitForTextOnScreen 方法可以 等待屏幕上指定文字 出现

参数为

  • text : 要等待的目标文本内容

  • exact : 是否完全匹配

缺省为 True , 表示必须完全和 text参数匹配,

如果为 False ,表示只需包含text参数内容即为点击目标

  • range : 目标文字的识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只在该范围内,搜寻目标文字,不在指定范围出现的目标文字不关心。

  • timeout : 超时时长,缺省值为10秒

每隔半秒检查屏幕上是否出现指定内容,如果出现,立即返回。

如果在指定时长内没有在屏幕上找到目标文字,抛出 RuntimeError 错误


返回值为 等待文字在屏幕上的坐标。


比如

device.waitForTextOnScreen('热招职位')


其实本函数等价于 以下面的方式调用 textPosOnScreen

device.textPosOnScreen(text, exact=exact, range=range, timeout=timeout)


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR

等待屏幕上指定文字消失

waitForTextNotOnScreen 方法可以 等待屏幕上指定文字 消失

参数为

  • text : 要等待的目标文本内容

  • exact : 是否完全匹配

缺省为 True , 表示必须完全和 text参数匹配,

如果为 False ,表示只需包含text参数内容即为点击目标

  • range : 目标文字的识别范围,缺省值为None,表示全屏识别。

比如 (0,0,1000,2000) , 依次为 左上角坐标,右下角坐标

设定识别范围后,只在该范围内,搜寻目标文字,不在指定范围出现的目标文字不关心。

  • timeout : 超时时长,缺省值为10秒

每隔半秒检查屏幕上指定内容是否消失,如果消失,立即返回。

如果在指定时长内目标文字仍然存在,抛出 RuntimeError 错误


比如

device.waitForTextNotOnScreen('热招职位')


该方法需要安装设置好OCR引擎, 缺省为 百度 PaddleOCR