控件查找器
from ascript.android.node import Selector
控件查找器,通过约束方法
,和查询方法
,来获取屏幕中满足条件的控件
.
方法
事件监听
监听设备的各种事件,有 窗口事件,视图事件,通知宣告事件,触摸和手势事件,其他事件等.
- 函数
Selector.on_event(listener)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
listener | python函数(event) | 是 | 回调函数,必须包含一个形式参数用来接收变化的事件 关于android.view.accessibility.AccessibilityEvent |
- 示例
# 监听吐司信息
# 导包
# 导入控件检索相关
from ascript.android.node import Selector
from android.view.accessibility import AccessibilityEvent
# 事件回调函数
def on_event(event):
# print(event)
e_tp = event.getEventType()
if e_tp == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
packageName = event.getPackageName()
message = ""
if event.getText() is not None and event.getText().size()>0:
message = event.getText().get(0)
print("来toast通知了",packageName,message)
# 开始监听无障碍事件
Selector.on_event(on_event)
控件缓存
是否启用控件缓存机制.
启用后,控件将不在刷新,请及时释放缓存
启用后,查找速度将有大幅度提升.
- 函数
Selector.cache(is_cache:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
is_cache | bool | 是 | True:打开缓存,缓存当前页面所有控件 False:关闭缓存 |
- 示例
# 开启缓存
from ascript.android.node import Selector
Selector.cache(True)
# 关闭控件缓存
from ascript.android.node import Selector
Selector.cache(False)
创建查找器
创建一个控件查找器
- 函数
#class
Selector(mode:int,xpath=None)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
mode | int | 否 | 检索模式 0(默认):普通检索模式,这种模式下只展示重要控件 1:复杂模式,这种模式下展示所有控件.层级会很深 2:简单模式下过滤掉系统控件. 3:复杂模式下过滤掉系统控件 6:Hid控件模式 9:Root模式 |
xpath | str | 否 | 使用xpath方式全局检索. |
- 示例
from ascript.android.node import Selector
# 创建一个选择器,简单模式检索
selector = Selector()
from ascript.android.node import Selector
# 创建一个选择器 ,复杂模式检索
Selector(1)
from ascript.android.node import Selector
# 创建一个选择器 ,简单模式,并且过滤掉系统控件
Selector(0|2)
from ascript.android.node import Selector
# 创建一个选择器 ,复杂模式,并且过滤掉系统控件
Selector(1|2)
from ascript.android.node import Selector
# 检索出所有控件类型是TextView的控件,并且text属性为开发者
Selector(xpath="//TextView[@text='开发者']")
查找控件一个
查找控件,返回一个满足条件的控件
- 函数
#class
Selector(mode:int).find()
- 返回值
Node 控件对象
- 示例
#案例:查找出符合条件的第一个控件
from ascript.android.node import Selector
node = Selector().find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
查找控件全部
查找控件,返回满足条件的控件
- 函数
#class
Selector(mode:int).find_all(num:int=999999)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
num | int | 否 | 控件结果最大数量 默认:满足条件的所有 |
- 返回值
Node[] 控件对象列表
- 示例
#案例:查找出所有符合条件的控件
from ascript.android.node import Selector
nodes = Selector().find_all()
if nodes:
#找到了一组控件
print( len(nodes) )
else:
print('没有找到任何控件')
获取控件树
获取完整的控件树, 返回Json树状格式
- 函数
#class
Selector.dump(mode:int=0)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
mode | int | 否 | 检索模式 0(默认):普通检索模式,这种模式下只展示重要控件 1:复杂模式,这种模式下展示所有控件.层级会很深 2:简单模式下过滤掉系统控件. 3:复杂模式下过滤掉系统控件 |
- 返回值
Json 数据 ,可转换为Python字典
- 示例
#案例:获取控件树json数据,并转换为字典
import json
# 导入节点检索模块
from ascript.android.node import Selector
res = Selector.dump()
print(res) # 这是json字符串
if res:
# 转换为字典对象
obj = json.loads(res);
print(obj)
属性约束
id
通过 id
约束
- 函数
Selector().id(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件ID,支持正则表达式,通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 导包
from ascript.android.node import Selector
# 查找id值为 “com.aojoy.airscript:id/search_bar_text” 的控件
node = Selector().id("com.aojoy.airscript:id/search_bar_text").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
# 案例2: 在id约束中使用正则表达式
# 导包
from ascript.android.node import Selector
# 查找id值为 ‘search_bar_text结尾’ 的控件 ,在正则中 ‘.’代表任何值,‘*’代表出现多次,‘^’代表以什么开头,‘$’代表以什么结尾
node = Selector().id(".*search_bar_text$").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
文本
通过 text
约束
- 函数
Selector().text(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 屏幕中显示的任意文本 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例1: 在text约束中使用完整文本
# 导包
from ascript.android.node import Selector
# 查找文本为 '开发者'
node = Selector().text("开发者").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
# 案例2: 在text约束中使用正则匹配 所有文本中包含 'AirScript' 的控件
# 导包
from ascript.android.node import Selector
# 查找 文本 中包含 了‘IP’ 的控件
nodes = Selector().text(".*IP.*").find_all()
if nodes:
#找到了控件
print( len(nodes))
else:
print('没有找到任何控件')
类型
通过 type
约束
- 函数
Selector().type(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件的类型 如:TextView, ListView 等等 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出 所有类型为 TextView 的控件
# 导包
from ascript.android.node import Selector
# 约束 type 为“TextView”
nodes = Selector().type("TextView").find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
描述
通过 控件描述desc
约束
- 函数
Selector().desc(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件的描述信息 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出 描述信息为 ‘这是关闭按钮’ 的控件
# 导包
from ascript.android.node import Selector
# 约束 desc 为“这是关闭按钮”
node = Selector().desc("这是关闭按钮").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
默认文本
通过控件 默认文本 hintText
约束
- 函数
Selector().hintText(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件的默认文本 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出 默认文本 包含 “小程序” 的控件
# 导包
from ascript.android.node import Selector
# 约束 hint_text 包含 “小程序” 的控件
node = Selector().hintText(".*小程序.*").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
包名
通过控件 包名 packageName
约束
- 函数
Selector().packageName(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件的所属包名 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出 包名 为 com.aojoy.airscript 的控件
from ascript.android.node import Selector
nodes = Selector().packageName("com.aojoy.airscript").find_all()
if nodes:
#找到了控件
print(nodes)
else:
print('没有找到任何控件')
路径
通过控件 路径 path
约束
- 函数
Selector().path(val:str)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | str正则 | 是 | 控件的路径 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出 路径 为 /FrameLayout/LinearLayout/FrameLayout/EditText 的控件
from ascript.android.node import Selector
node = Selector().path("/FrameLayout/LinearLayout/FrameLayout/EditText").find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
子控件数量
通过控件 子控件数量 childCount
约束
- 函数
Selector().childCount(val:int)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | int | 是 | 子控件的数量 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例1: 查找 子控件个数 为 13 的控件
# 导包
from ascript.android.node import Selector
node = Selector().childCount(13).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
#案例2: 查找 子控件个数 为 6-7 之间, 9-13 之间的 所有
# 导包
from ascript.android.node import Selector
# 约束 desc 为“这是关闭按钮”
nodes = Selector().childCount(6.7,9.13).find_all()
if nodes:
#找到了控件
for n in nodes:
print(n)
else:
print('没有找到任何控件')
输入类型
通过控件 输入类型 inputType
约束
- 函数
Selector().inputType(val:int)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | int | 是 | 控件的输入类型 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找输入类型为 524289 的 控件
# 导包
from ascript.android.node import Selector
# 约束 输入类型 为1
node = Selector().inputType(524289).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
绘制排序
通过控件 绘制排序 drawingOrder
约束
绘制排序,部分情况下会变化.请不要过度依赖该属性
- 函数
Selector().drawingOrder(val:int)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | int | 是 | 控件的绘制排名 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找出 绘制序列属性 为38的控件
# 导包
from ascript.android.node import Selector
# 约束 drawingOrder 属性为2的控件
node = Selector().drawingOrder(38).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
控件深度
通过控件 控 件深度 depth
约束
- 函数
Selector().depth(val:int):
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | int | 是 | 控件的层级深度 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找出 绘制深度属性 为4的控件
# 导包
from ascript.android.node import Selector
node = Selector().depth(4).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
最大文本长度
通过控件 最大文本长度 maxTextLength
约束
- 函数
Selector().maxTextLength(val:int)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | int | 是 | 控件的最大文本内容长度 通常用控件查找器获取 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找最大文本长度 限制为 5000 的 控件
# 导包
from ascript.android.node import Selector
# 约束 最大文本长度 为 50
node = Selector().maxTextLength(5000).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
是否可点击 约束
通过控件 clickable
约束
- 函数
Selector().clickable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可以点击 ,False:不可点击 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案 例: 查找出当前页面中 所有可以被点击的控件
# 导包
from ascript.android.node import Selector
# 约束 可以点击
nodes = Selector().clickable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否可以被选中
通过控件 checkable
约束
- 函数
Selector().checkable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可被选中 ,False:不可被选中 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有可以选中的控件
# 导包
from ascript.android.node import Selector
# 约束 可以选中
nodes = Selector().checkable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否选中
通过控件 checked
约束
- 函数
Selector().checked(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:已选中 ,False:未选中 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找出当前页面中 所有已经选中的控件
# 导包
from ascript.android.node import Selector
# 约束 可以选中
nodes = Selector().checked(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否可编辑
通过控件 editable
约束
- 函数
Selector().editable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可编辑 ,False:不可编辑 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有可以编辑文本的控件
# 导 包
from ascript.android.node import Selector
# 约束 可以编辑
nodes = Selector().editable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否可访问
通过控件 enabled
约束
- 函数
Selector().enabled(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可操作,如点击,输入 ,False:不可操作,点击,输入无效 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有不可以访问的控件
# 导包
from ascript.android.node import Selector
# 约束 不可以访问
nodes = Selector().enabled(False).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否可被关闭
通过控件 dismissable
约束
- 函数
Selector().dismissable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可关闭 ,False:不可关闭 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有可以被关闭的控件
# 导包
from ascript.android.node import Selector
# 约束 不可以访问
nodes = Selector().dismissable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否可以获取焦点
通过控件 focusable
约束
- 函数
Selector().focusable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:可获取焦点 ,False:不允许获取焦点 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找出当前页面中 所有所有可以被获取焦点的控件
# 导包
from ascript.android.node import Selector
# 约束 可以获取焦点的控件
nodes = Selector().focusable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否有焦点
通过控件 focused
约束
- 函数
Selector().focused(val:bool)
- 参数
参数 | 类型 | 是否 必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:已获取焦点 ,False:没有焦点 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有所有可以被获取焦点的控件
# 导包
from ascript.android.node import Selector
# 约束 已经获取焦点
node = Selector().focused(True).find()
if node:
#找到了控件
print(node)
else:
print('没有找到任何控件')
是否显示中
通过控件 visible
约束
- 函数
Selector().visible(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:显示在屏幕上 False:隐藏或在屏幕之外 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例: 查找出,所有用户不可见的控件
# 导包
from ascript.android.node import Selector
nodes = Selector().visible(False).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
是否支持长按
通过控件 longClickable
约束
- 函数
Selector().longClickable(val:bool)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
val | bool | 是 | True:支持 False:不支持 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
#案例: 查找出当前页面中 所有支持长按的控件
# 导包
from ascript.android.node import Selector
# 约束 已经获取焦点
nodes = Selector().longClickable(True).find_all()
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
关系约束
获取父控件
通过控件 parent
约束
- 函数
Selector().parent(*val:float)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
*val | float可变参数 | 是 | 获取第val个父控件默认获取所有父元素 (2):获取爷爷元素 (3):获取太爷爷元素 (1,3):获取第1和第3个父元素 (1.3):获取第1-3 之间的所有父元素 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例1: 获取指定 id控件的 所有父元素(父元素,爷爷元素,太爷爷,祖太爷...统统获取)
# 导包
from ascript.android.node import Selector
# 约束 获取所有父元素
nodes = Selector().id("com.aojoy.airscript:id/search_bar_text").parent().find_all();
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
# 案例2: 获取指定 id控件的 太爷爷元素
# 导包
from ascript.android.node import Selector
nodes = Selector().id("com.aojoy.airscript:id/search_bar_text").parent(3).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
# 案例3: 获取父元素,太太爷元素
# 导包
from ascript.android.node import Selector
nodes = Selector().id("com.aojoy.airscript:id/search_bar_text").parent(1,3).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
# 案例4: 获取往上数3辈 所有元素
# 导包
from ascript.android.node import Selector
# 约束 获取1-3 之间的所有父元素
nodes = Selector().id("com.aojoy.airscript:id/search_bar_text").parent(1.3).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node)
else:
print('没有找到任何控件')
获取子控件
通过控件 child
约束
- 函数
Selector().child(*val:float)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
*val | float可变参数 | 是 | 获取第val个子控件默认获取所有孩子控件 (1):获取第1个孩子控件 (-1):获取倒数第1个孩子 (1.3):获取1-3之间的所有孩子 (-1.3):获取倒数 1-3之间的所有孩子 (1,3):获取第1个和第3个子控件 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例1: 获取所有孩子
# 导包
from ascript.android.node import Selector
# 约束 默认无参下,获取所有
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child().find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
# 案例2: 获取第一个孩子
# 导包
from ascript.android.node import Selector
# 约束 获取第一个孩子
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child(1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
# 案例3: 获取第1和 第2个孩子
# 导包
from ascript.android.node import Selector
# 约束 可变参数,填写多个
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child(1,2).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
# 案例4: 获取第1-3个孩子
# 导包
from ascript.android.node import Selector
# 约束 填写一个小数,获取区间孩子
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child(1.3).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
# 案例5: 获取第倒数第一个孩子
# 导包
from ascript.android.node import Selector
# 约束 负数,倒数取值
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child(-1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
# 案例6: 获取第倒数第1-3 个孩子
# 导包
from ascript.android.node import Selector
# 约束 负数,倒数区间取值
nodes = Selector().id("com.aojoy.airscript:id/search_query_section").child(-1.3).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.type)
else:
print('没有找到任何控件')
获取兄弟控件
通过控件 brother
约束
- 函数
Selector().brother(*val:float)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
*val | float可变参数 | 是 | 获取第val个子控件默认获取所有兄弟控件 (1):获取第1个兄弟控件 (1,2):获取第1和第2个兄弟控件 (1.4):获取1-4之间的所有兄弟控件 (0.1):获取当前控件的下一个兄弟控件 (-0.1):获取当前控件的上一个兄弟控件 (-1):获取倒数第1个兄弟控件 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 案例1: 获取所有兄弟
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother().find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例2: 获取第一个兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例3: 获取第1和第2个兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(1,2).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例4:获取1-4之间的所有兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(1.4).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例5:获取当前控件的下一个兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(0.1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例6:获取当前控件的上一个兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(-0.1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
# 案例7:获取倒数第1个兄弟控件
# 导包
from ascript.android.node import Selector
nodes = Selector().desc(".*充电.*").brother(-1).find_all();
if nodes:
#找到了控件
for node in nodes:
print(node.desc)
else:
print('没有找到任何控件')
动作约束
点击控件
通过控件 click
约束
- 函数
Selector().click()
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 查找 到指定控件,执行点击方法, “点击方法也是约束的一种,因此不能忘记后面的find或_find_all”
#导包
from ascript.android.node import Selector
Selector().type("ImageView").id("com.aojoy.airscript:id/iv_statue1").click().find()
长按控件
通过控件 long_click
约束
- 函数
Selector().long_click()
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 指定控件 长按操作
from ascript.android.node import Selector
node = Selector().id("com.aojoy.airscript:id/gv_historyrun").child(1).long_click().find()
滑动控件
通过控件 slide
约束
- 函数
Selector().slide(ore:int=1)
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
ore | int | 是 | 滑动方向1:向前滑动-(默认) -1:向后滑动 |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 查找 到指定可控件 ,执行向后滑动
#导包
from ascript.android.node import Selector
Selector().type("RecyclerView").slide(1).find()
向控件输入信息
通过控件 input
约束
- 函数
Selector().input(msg:str="")
- 参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
msg | str | 否 | 输入的信息"":清空输入框中的值 (默认) |
- 返回值
Selector 返回控件查找器,用于链式编程
- 示例
# 查找 到指定可控件 , 输入‘自在老师’
#导包
from ascript.android.node import Selector
Selector().id("com.aojoy.airscript:id/search_bar_text").input("自在老师").find()
附录
AccessibilityEvent 事件类型详解
# 导包
from android.view.accessibility import AccessibilityEvent
当启动无障碍后,我们可以接收到无障碍的各种事件反馈.
AccessibilityEvent
对象可以表示多种用户界面上发生的事件。这些事件类型由 AccessibilityEvent.getEventType()
返回的整数常量定义。以下是 AccessibilityEvent
中定义的主要事件类型常量:
窗口级事件 (Window Level Events)
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
- 描述: 窗口状态发生了变化,例如窗口出现 、消失、获取焦点、失去焦点,或者窗口的标题、层级等属性改变。
- 用途: 检测新窗口的打开(如对话框、菜单、新的 Activity),或者窗口焦点的切换。Toast 在旧版本中可能表现为窗口状态变化。
AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
- 描述: 窗口的内容发生了变化。这可能是由于视图的添加/移除、文本内容的改变、列表的滚动等。
- 用途: 这是非常通用的事件,可以用来检测UI上的几乎所有可见变化。捕获 Toast 内容、输入框文本变化、列表项更新等。
AccessibilityEvent.TYPE_WINDOWS_CHANGED
(API 24+)
- 描述: 屏幕上的窗口集合发生了变化,例如添加、移除或重新排序窗口。这提供了比
TYPE_WINDOW_STATE_CHANGED
更宏观的窗口变化视图。 - 用途: 检测应用切换,画中画模式变化等。
视图级事件 (View Level Events)
AccessibilityEvent.TYPE_VIEW_CLICKED
- 描述: 一个视图被点击了 (通过用户触摸或无障碍操作)。
- 用途: 监听按钮点击、列表项点击等。
AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
- 描述: 一个视图被长按了。
- 用途: 监听视图的长按操作。
AccessibilityEvent.TYPE_VIEW_FOCUSED
- 描述: 一个视图获得了无障碍焦点 (Accessibility Focus),不同于输入焦点 (Input Focus)。无障碍焦点通常用于屏幕阅读器导航。
- 用途: 追踪屏幕阅读器当前聚焦的元素。
AccessibilityEvent.TYPE_VIEW_SELECTED
- 描述: 一个视图被选中了 (例如,在一个可选择的列表或标签组中)。
- 用途: 监听
AdapterView
(如Spinner
,ListView
) 中项目的选择。
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
- 描述: 一个可编辑视图 (如
EditText
) 中的文本内容发生了变化。 - 用途: 监听用户输入、文本粘贴等。
AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
- 描述: 一个视图中的文本选择范围发生了变化。
- 用途: 监听文本的选中、复制、剪切操作。
AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
- 描述: 指针 (如鼠标或触摸笔) 进入了一个视图的边界。
- 用途: 主要用于支持鼠标或触摸笔等指针设备的交互。
AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
- 描述: 指针离开了一个视图的边界。
- 用途: 同上。
AccessibilityEvent.TYPE_VIEW_SCROLLED
- 描述: 一个可滚动的视图 (如
ScrollView
,ListView
,RecyclerView
) 的内容发生了滚动。 - 用途: 检测列表或页面的滚动。
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
(API 16+)
- 描述: 一个视图获得了无障碍焦点。与
TYPE_VIEW_FOCUSED
类似,但更明确。 - 用途: 同
TYPE_VIEW_FOCUSED
。
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
(API 16+)
- 描述: 无障碍焦点从一个视图上被清除了。
- 用途: 追踪无障碍焦点的移除。
AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
(API 16+)
- 描述: 当用户以特定粒度(如字符、单词、行)遍历文本时触发。
- 用途: 主要用于屏幕阅读器在文本中导航。
通知和宣告事件 (Notification and Announcement Events)
AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED
- 描述: 通知状态发生了变化。这通常指的是状态栏通知 (StatusBar Notification) 的出现、更新或移除。在非常早期的 Android 版 本中,有时也用来间接捕获 Toast,但现在不推荐。
- 用途: 监听状态栏通知。
AccessibilityEvent.TYPE_ANNOUNCEMENT
(API 16+)
- 描述: 应用请求无障碍服务向用户宣告某些信息。这通常用于屏幕阅读器朗读动态更新的内容,或者在 Android 11 (API 30) 及更高版本中,Toast 的内容也通过此事件宣告。
- 用途: 捕获应用希望朗读给用户的信息,以及高版本 Android 上的 Toast。
AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT
(API 26+)
- 描述: 当系统或助手应用尝试读取当前屏幕的上下文信息时触发。
- 用途: 允许无障碍服务提供更丰富的上下文信息给助手应用。
触摸和手势事件 (Touch and Gesture Events)
AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START
- 描述: 用户开始通过触摸探索屏幕上的内容(通常是屏幕阅读器用户)。
- 用途: 检测触摸探索模式的开始。
AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END
- 描述: 用户结束了触摸探索。
- 用途: 检测触摸探索模式的结束。
AccessibilityEvent.TYPE_TOUCH_INTERACTION_START
(API 21+)
- 描述: 用户开始与屏幕进行触摸交互。
- 用途: 更通用的触摸开始事件。
AccessibilityEvent.TYPE_TOUCH_INTERACTION_END
(API 21+)
- 描述: 用户结束了与屏幕的触摸交互。
- 用途: 更通用的触摸结束事件。
AccessibilityEvent.TYPE_GESTURE_DETECTION_START
(API 23+)
- 描述: 系统开始检测无障碍手势。
- 用途: 与自定义无障碍手势相关。
AccessibilityEvent.TYPE_GESTURE_DETECTION_END
(API 23+)
- 描述: 系统结束检测无障碍手势。
- 用途: 同上。
其他事件
AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED
(API 23+)
- 描述: 一个视图被 上下文点击了 (通常是鼠标右键点击或类似操作)。
- 用途: 监听上下文菜单的触发。
AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_APPEARED
- (作为
TYPE_WINDOW_CONTENT_CHANGED
的getContentChangeTypes()
之一, API 28+) - 描述: 表示一个新的窗格 (pane) 出现在屏幕上。
AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED
- (同上, API 28+)
- 描述: 一个窗格从屏幕上消失。
AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_TITLE
- (同上, API 28+)
- 描述: 一个窗格的标题发生变化。
- (还有其他
CONTENT_CHANGE_TYPE_*
常量,用于更细致地描述TYPE_WINDOW_CONTENT_CHANGED
的原因)
* 如何选择事件类型
- 监听 Toast: 主要关注
TYPE_WINDOW_CONTENT_CHANGED
和TYPE_WINDOW_STATE_CHANGED
(旧版本),以及TYPE_ANNOUNCEMENT
(Android 11+)。 - 监听文本输入: 使用
TYPE_VIEW_TEXT_CHANGED
。 - 监听点击: 使用
TYPE_VIEW_CLICKED
。 - 通用 UI 变化:
TYPE_WINDOW_CONTENT_CHANGED
是一个覆盖面很广的事件。
* 重要提示
AccessibilityEvent
对象还包含许多其他有用的信息,如getPackageName()
,getClassName()
,getText()
,getContentDescription()
,getSource()
(获取事件源AccessibilityNodeInfo
) 等,你需要结合事件类型和这些信息来理解事件的具体含义。
- 某些事件类型可能需要特定的
AccessibilityServiceInfo.flags
才能接收到或获取到完整的事件信息。例如,FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
或FLAG_RETRIEVE_INTERACTIVE_WINDOWS
。 - 始终查阅最新的 Android 官方文档以获取最准确和最全面的信息,因为这些 API 可能会随着 Android 版本的更新而演进。