- Global - 全局对象
- Automator - 自动化
- AutoJs6 - 本体应用
- App - 通用应用
- Color - 颜色
- Image - 图像
- OCR - 光学字符识别
- Barcode - 条码
- QR Code - 二维码
- Keys - 按键
- Device - 设备
- Storage - 储存
- File - 文件
- Engine - 引擎
- Task - 任务
- Module - 模块
- Plugins - 插件
- Toast - 消息浮动框
- Notice - 消息通知
- Console - 控制台
- Shell
- Shizuku
- Media - 多媒体
- Sensor - 传感器
- Recorder - 记录器
- Timer - 定时器
- Thread - 线程
- Continuation - 协程
- Event - 事件监听
- Dialog - 对话框
- Floaty - 悬浮窗
- Canvas - 画布
- UI - 用户界面
- Web - 万维网
- HTTP
- Base64
- Crypto - 密文
- OpenCC - 中文转换
- Internationalization - 国际化
- Standardization - 标准化
- E4X
- UiSelector - 选择器
- UiObject - 控件节点
- UiObjectCollection - 控件集合
- UiObjectActions - 控件节点行为
- WebSocket
- EventEmitter - 事件发射器
- ImageWrapper - 包装图像类
- App - 应用枚举类
- Color - 颜色类
- Version - 版本工具类
- Polyfill - 代码填泥
- Arrayx - Array 扩展
- Numberx - Number 扩展
- Mathx - Math 扩展
- Glossaries - 术语
- HttpHeader - HTTP 标头
- HttpRequestMethods - HTTP 请求方法
- MimeType - MIME 类型
- NotificationChannel - 通知渠道
- Data Types - 数据类型
- Omnipotent Types - 全能类型
- Storage - 存储类
- AndroidBundle
- AndroidRect
- CryptoCipherOptions
- CryptoKey
- CryptoKeyPair
- ConsoleBuildOptions
- HttpRequestBuilderOptions
- HttpRequestHeaders
- HttpResponseBody
- HttpResponseHeaders
- HttpResponse
- InjectableWebClient
- InjectableWebView
- NoticeOptions
- NoticeChannelOptions
- NoticePresetConfiguration
- NoticeBuilder
- Okhttp3HttpUrl
- OcrOptions
- Okhttp3Request
- OpenCVPoint
- OpenCVRect
- OpenCVSize
- OpenCCConversion
AutoJs6 文档 - 6.6.4
目录
- 控件节点行为 (UiObjectActions)
- [m!] performAction
- [m=] click
- [m=] longClick
- [m=] accessibilityFocus
- [m=] clearAccessibilityFocus
- [m=] focus
- [m=] clearFocus
- [m=] dragStart
- [m=] dragDrop
- [m=] dragCancel
- [m=] imeEnter
- [m=] moveWindow
- [m=] nextAtMovementGranularity
- [m=] nextHtmlElement
- [m=] pageLeft
- [m=] pageUp
- [m=] pageRight
- [m=] pageDown
- [m=] pressAndHold
- [m=] previousAtMovementGranularity
- [m=] previousHtmlElement
- [m=] showTextSuggestions
- [m=] showTooltip
- [m=] hideTooltip
- [m=] show
- [m=] dismiss
- [m=] copy
- [m=] cut
- [m=] paste
- [m=] select
- [m=] expand
- [m=] collapse
- [m=] scrollLeft
- [m=] scrollUp
- [m=] scrollRight
- [m=] scrollDown
- [m=] scrollForward
- [m=] scrollBackward
- [m=] scrollTo
- [m=] contextClick
- [m=] setText
- [m=] setSelection
- [m=] clearSelection
- [m=] setProgress
- [I] ActionArgument
- 全局行为重定向
控件节点行为 (UiObjectActions)#
UiObjectActions 是一个 Java 接口, 代表 控件节点 (UiObject) 的行为集合.
该接口有一个抽象方法 performAction 是执行具体的控件节点行为的核心.
诸如 [ click / copy / paste ] 等方法均是对 performAction 的封装, 因此用户也可利用 performAction 实现自定义控件节点行为的封装.
下表列出了部分行为 ID 名称, 及对应已实现封装的方法名称 (星号表示 AutoJs6 新增方法):
行为 ID | 封装方法名 | 最低 API 等级 |
---|---|---|
ACTION_ACCESSIBILITY_FOCUS | accessibilityFocus | - |
ACTION_CLEAR_ACCESSIBILITY_FOCUS | clearAccessibilityFocus | - |
ACTION_CLEAR_FOCUS | clearFocus | - |
ACTION_CLEAR_SELECTION | clearSelection * | - |
ACTION_CLICK | click | - |
ACTION_COLLAPSE | collapse | - |
ACTION_CONTEXT_CLICK | contextClick | - |
ACTION_COPY | copy | - |
ACTION_CUT | cut | - |
ACTION_DISMISS | dismiss | - |
ACTION_DRAG_CANCEL | dragCancel * | 32 (12.1) [S_V2] |
ACTION_DRAG_DROP | dragDrop * | 32 (12.1) [S_V2] |
ACTION_DRAG_START | dragStart * | 32 (12.1) [S_V2] |
ACTION_EXPAND | expand | - |
ACTION_FOCUS | focus | - |
ACTION_HIDE_TOOLTIP | hideTooltip * | 28 (9) [P] |
ACTION_IME_ENTER | imeEnter * | 30 (11) [R] |
ACTION_LONG_CLICK | longClick | - |
ACTION_MOVE_WINDOW | moveWindow * | 26 (8) [O] |
ACTION_NEXT_AT_MOVEMENT_GRANULARITY | nextAtMovementGranularity * | - |
ACTION_NEXT_HTML_ELEMENT | nextHtmlElement * | - |
ACTION_PAGE_DOWN | pageDown * | 29 (10) [Q] |
ACTION_PAGE_LEFT | pageLeft * | 29 (10) [Q] |
ACTION_PAGE_RIGHT | pageRight * | 29 (10) [Q] |
ACTION_PAGE_UP | pageUp * | 29 (10) [Q] |
ACTION_PASTE | paste | - |
ACTION_PRESS_AND_HOLD | pressAndHold * | 30 (11) [R] |
ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY | previousAtMovementGranularity * | - |
ACTION_PREVIOUS_HTML_ELEMENT | previousHtmlElement * | - |
ACTION_SCROLL_BACKWARD | scrollBackward | - |
ACTION_SCROLL_DOWN | scrollDown | - |
ACTION_SCROLL_FORWARD | scrollForward | - |
ACTION_SCROLL_LEFT | scrollLeft | - |
ACTION_SCROLL_RIGHT | scrollRight | - |
ACTION_SCROLL_TO_POSITION | scrollTo | - |
ACTION_SCROLL_UP | scrollUp | - |
ACTION_SELECT | select | - |
ACTION_SET_PROGRESS | setProgress | - |
ACTION_SET_SELECTION | setSelection | - |
ACTION_SET_TEXT | setText | - |
ACTION_SHOW_ON_SCREEN | show | - |
ACTION_SHOW_TEXT_SUGGESTIONS | showTextSuggestions * | 33 (13) [TIRAMISU] |
ACTION_SHOW_TOOLTIP | showTooltip * | 28 (9) [P] |
若当前设备不满足列表中最低 API 等级要求, 使用对应方法时不会抛出异常, 会静默返回 false:
/*
例如 ACTION_IME_ENTER 要求设备运行条件不低于 Android API 30 (11) [R].
在 API < 30 的设备上一定返回 false 且 IME ENTER 无效果 (但不会抛出异常).
*/
console.log(pickup({
focusable: true,
contentMatch: '.+',
}, 'imeEnter'));
上表中所有已封装的控件行为对应的方法 名称 均已全局化, 有关全局化方法的使用方式及方法的绑定源信息, 可参阅 全局行为重定向 小节.
参阅: Android Docs
UiObjectActions
[m!] performAction#
用于执行指定的控件行为.
是一个无默认实现的抽象方法.
performAction(action, ...arguments)#
A11Y
- action { number } - 行为的唯一标志符 (Action ID)
- arguments { ...ActionArgument[] } - 行为参数, 用于给行为传递参数
- returns { boolean } - 是否行为已执行且执行过程中无异常
实现此方法的类有:
源代码摘要:
- UiSelector
/* Updated as of Nov 2, 2022. */
override fun performAction(action: Int, vararg arguments: ActionArgument): Boolean {
return untilFind().performAction(action, *arguments)
}
- UiObject
/* Updated as of Nov 2, 2022. */
override fun performAction(action: Int, vararg arguments: ActionArgument): Boolean {
return performAction(action, Bundle().apply { arguments.forEach { it.putIn(this) } })
}
override fun performAction(action: Int, bundle: Bundle): Boolean = try {
when (bundle.isEmpty) {
true -> super.performAction(action)
else -> super.performAction(action, bundle)
}
} catch (e: IllegalStateException) {
false
}
- UiObjectCollection
/* Updated as of Nov 2, 2022. */
override fun performAction(action: Int, vararg arguments: ActionArgument): Boolean {
var success = true
nodes.filterNotNull().forEach { node ->
when (arguments.isEmpty()) {
true -> node.performAction(action)
else -> node.performAction(action, *arguments)
}.also { success = success and it }
}
return success
}
由此可见, UiSelector 与 UiObjectCollection 最终都调用了 UiObject 的 performAction
方法, 而 UiObject
的 performAction
则调用了 Android 系统的 AccessibilityNodeInfoCompat#performAction) 方法
UiObjectCollection
相当于对控件集合中的每一个控件执行 UiObject#performAction
方法.UiSelector
相当于先执行 untilFind 找到当前窗口中所有控件, 将其作为集合执行 UiObjectCollection#performAction
方法.
因全局的 untilFind()
是 "无条件" 筛选, 会把窗口中所有控件 (往往会有几十甚至成百上千个控件) 全部加入集合中, 此时执行任何 行为 (Action)
, 都相当于集合中所有控件执行一遍上述行为, 这样的操作往往是无意义的, 很可能造成非预期结果甚至不可控的操作, 因此不建议使用 UiSelector
提供的 行为 (Action)
方法.
下面列举一个 UiSelector
提供的行为, 再次强调不建议使用:
/* ACTION_SET_TEXT 行为 */
/* 对当前窗口中所有支持设置文本的控件, 将内容设置为 "hello". */
selector().setText("hello");
/* UiSelector 几乎所有方法均已全局化, setText 位列其中. */
setText("hello"); /* 效果同上. */
如有上述示例的需求 (对控件设置文本内容), 而且是针对多个控件同时设置, 建议使用选择器定位指定的控件集合, 再统一执行 行为 (Action)
:
/* 先筛选集合. */
let nodes = pickup({
focusable: true,
textMatch: "name",
boundInside: [ cX(0.2), cYx(0.04), cX(0.8), cY(0.92) ],
}, '[w]');
/* 再执行行为. */
nodes.forEach(w => w.setText("hello"));
如需对控件执行自定义行为, 可通过 UiObject#performAction
实现:
/* 对控件执行 ACTION_IME_ENTER 行为. */
let { AccessibilityActionCompat } = androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
let w = focusable().contentMatch(/name/).findOnce();
w.performAction(AccessibilityActionCompat.ACTION_IME_ENTER.id);
有些 行为 (Action)
需要指定参数, 此时可借助 ActionArgument 接口传入参数:
/* 对控件执行 ACTION_SET_TEXT 及 ACTION_SET_SELECTION 行为. */
let { AccessibilityNodeInfoCompat } = androidx.core.view.accessibility
let { AccessibilityActionCompat } = AccessibilityNodeInfoCompat;
let { ActionArgument } = org.autojs.autojs.core.automator;
let w = focusable().contentMatch(/name/).findOnce();
/* ACTION_SET_TEXT 需要一个 ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE "行为参数". */
w.performAction(
AccessibilityActionCompat.ACTION_SET_TEXT.id,
ActionArgument.CharSequenceActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "hello"),
);
/* ACTION_SET_SELECTION 需要两个 "行为参数", */
/* ACTION_ARGUMENT_SELECTION_START_INT 及 ACTION_ARGUMENT_SELECTION_END_INT. */
w.performAction(
AccessibilityActionCompat.ACTION_SET_SELECTION.id,
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, 1),
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, 4),
);
UiObject
拥有另一个实例方法 performAction(action, bundle), 因此上述示例也可改写为:
let arguments = new android.os.Bundle();
arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, 1);
arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, 4);
w.performAction(AccessibilityActionCompat.ACTION_SET_SELECTION.id, arguments);
如需判断控件是否有某个或某些 Action
, 可使用 UiObject#hasAction:
console.log(w.hasAction("ACTION_CLICK"));
console.log(w.hasAction("CLICK")); /* 前缀 "ACTION_" 可省略. */
/* 检查是否同时拥有多个 Action. */
console.log(w.hasAction("CLICK", "IME_ENTER", "SCROLL_UP"));
如需使用 Action
选择器筛选控件, 可使用 UiSelector#action:
console.log(action("ACTION_CLICK").findOnce());
console.log(action("CLICK").findOnce()); /* 前缀 "ACTION_" 可省略. */
/* 筛选多个 Action. */
console.log(action("CLICK", "IME_ENTER", "SCROLL_UP").findOnce());
[m=] click#
click()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 点击 ] 行为.
检查一个控件节点是否可点击:
console.log(w.clickable());
console.log(w.isClickable()); /* 同上. */
以下情况可能导致 w.click()
返回 false
:
- 控件不可点击 (
w.clickable()
为false
) - 页面无法响应点击事件
有时会出现虽然 w
不可点击但 w.parent()
或 w.parent().parent()
等父级控件可点击的情况:
function tryClick(w) {
let max = 3;
let tmp = w;
while (max--) {
tmp = tmp.parent();
if (tmp.isClickable()) {
return tmp.click();
}
}
return false;
}
console.log(tryClick(w));
/* 上述过程可使用 pickup 简化. */
console.log(pickup(w, 'k3', 'click'));
使用控件的 click
方法主要优缺点 (相较于坐标模拟点击):
- [优] 速度较快
- [优] 适用于位置不断变化的控件
- [优] 适用于不在窗口可视化范围内的控件
- [优] 适用于上层被其他控件覆盖或遮挡的控件
- [劣] 部分控件难以通过选择器精确定位
- [劣] 部分控件执行
click
行为后无响应 - [劣] 无法完全适应控件属性或层级关系改变的情况
鉴于上述优劣项, 控件的 click
方法通常与 [ global.click (automator.click) / UiObject#clickByBounds ] 等方法配合使用.
[m=] longClick#
longClick()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 长按 ] 行为.
检查一个控件节点是否可长按:
console.log(w.longClickable());
console.log(w.isLongClickable()); /* 同上. */
以下情况可能导致 w.longClick()
返回 false
:
- 控件不可长按 (
w.longClickable()
为false
) - 页面无法响应长按事件
[m=] accessibilityFocus#
accessibilityFocus()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 获取无障碍焦点 ] 行为.
只有在当前设备启用了无障碍软件 (如 TalkBack) 才能正常使用 accessibilityFocus().
以 TalkBack 为例, 启用后, 当前窗口中获取无障碍焦点的控件将被绿色方框标记其边界, 此时按下键盘回车键或无障碍设备 (如 D-pad) 的确定键 (取决于不同设备), 即可激活此控件.
/* 获得无障碍焦点. */
console.log(pickup(idEndsWith('fab'), 'accessibilityFocus')); /* boolean 类型结果. */
/* 检查是否已获得无障碍焦点. */
console.log(pickup(idEndsWith('fab'), 'accessibilityFocused')); /* boolean 类型结果. */
如需清除焦点, 可使用 clearAccessibilityFocus 方法.
[m=] clearAccessibilityFocus#
clearAccessibilityFocus()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 清除无障碍焦点 ] 行为.
只有在当前设备启用了无障碍软件 (如 TalkBack) 才能正常使用 clearAccessibilityFocus().
/* 清除无障碍焦点. */
console.log(pickup(idEndsWith('fab'), 'clearAccessibilityFocus')); /* boolean 类型结果. */
[m=] focus#
focus()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 获取焦点 ] 行为.
在当前设备连接外置键盘等输入设备时, 按下 TAB 或 方向键可在控件之间 "切换", 这些控件都是 focusable (可被聚焦) 的.
/* 查看控件是否可被聚焦. */
console.log(w.focusable());
console.log(w.isFocusable()); /* 同上. */
当控件被聚焦 (即获取焦点) 后, 可使用输入设备的 ENTER 或 OK 等表示确认的按键激活此控件.
如果此控件支持文本输入 (例如常见的 EditText 类型控件), 在被聚焦后, 将出现输入光标, 且可能会弹出软键盘用于用户输入内容.
/* 打印当前窗口支持聚焦的控件文本内容数组. */
console.log(pickup({ focusable: true }, 'txt[]'));
/* 按文本内容筛选一个控件并使其获得焦点. */
pickup([ { focusable: true }, /search/ ], 'focus');
如需清除焦点, 可使用 clearFocus 方法.
[m=] clearFocus#
clearFocus()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 清除焦点 ] 行为.
对一个可被聚焦的控件, 如果它没有获得焦点, 调用 clearFocus 方法时将返回 false.
/* w 可被聚焦, 但当前未获得焦点. */
console.log(w.focusable()); // true
console.log(w.isFocused()); // false
/* isFocused 返回 false, 因此 clearFocus 也返回 false. */
console.log(w.clearFocus()); // false
[m=] dragStart#
dragStart()#
6.2.0
A11Y
API>=32
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 拖放开始 ] 行为.
此操作将初始化系统内部的拖放 (Drag & Drop) 功能.
支持拖放的内容将在拖放行为开始前完成准备.
[m=] dragDrop#
dragDrop()#
6.2.0
A11Y
API>=32
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 拖放放下 ] 行为.
此操作针对于已开始 ACTION_DRAG_START 行为的拖放目标.
[m=] dragCancel#
dragCancel()#
6.2.0
A11Y
API>=32
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 拖放取消 ] 行为.
此操作针对于已开始 ACTION_DRAG_START 行为的拖放目标.
[m=] imeEnter#
imeEnter()#
6.2.0
A11Y
API>=30
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 输入法 ENTER 键 ] 行为.
此操作通常只对获得焦点且可编辑的控件有效.
通常 imeEnter 用来模拟回车键在文本控件实现换行功能.
另外也可以模拟某些表示确认的操作, 如 [ 搜索 / 发送 / 下一步 / 立即前往 / 开始执行 ] 等.
/* 模拟回车键. */
console.log(pickup({
className: 'EditText',
focused: true,
}, 'imeEnter')); /* e.g. true */
[m=] moveWindow#
moveWindow(x, y)#
6.2.0
A11Y
API>=26
控件节点执行 [ 移动窗口到新位置 ] 行为.
[m=] nextAtMovementGranularity#
nextAtMovementGranularity(granularity, isExtendSelection)#
6.2.0
A11Y
- granularity { number } - 粒度
- isExtendSelection { boolean } - 是否扩展选则文本
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 按粒度移至下一位置 ] 行为.
按指定粒度移动光标到下一个文本实体位置, 例如移动到下一个单词, 下一行, 下一个段落等.
const AccessibilityNodeInfo = android.view.accessibility.AccessibilityNodeInfo;
let w = pickup([ /.+/, { className: 'EditText' } ]);
/* 按 WORD (单词) 粒度移动. */
/* 除 WORD 外, 还支持 CHARACTER (字符), LINE (行), PARAGRAPH (段落), PAGE (页) 等粒度. */
w.nextAtMovementGranularity(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD, false);
[m=] nextHtmlElement#
nextHtmlElement(element)#
6.2.0
A11Y
控件节点执行 [ 按元素移至下一位置 ] 行为.
按指定元素名称移动焦点至下一元素位置, 例如移动到下一个按钮, 下一个列表, 下一个输入框等.
console.log(w.nextHtmlElement("BUTTON"));
[m=] pageLeft#
pageLeft()#
6.2.0
A11Y
API>=29
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗左移的翻页 ] 行为.
此操作使视窗向左移动, 以便将可翻页控件左侧的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向右拖动视图.
- 新可视化内容: 左.
- 视窗移动方向: 左.
- 视图移动方向: 右.
[m=] pageUp#
pageUp()#
6.2.0
A11Y
API>=29
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗上移的翻页 ] 行为.
此操作使视窗向上移动, 以便将可翻页控件上方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向下拖动视图.
- 新可视化内容: 上.
- 视窗移动方向: 上.
- 视图移动方向: 下.
[m=] pageRight#
pageRight()#
6.2.0
A11Y
API>=29
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗右移的翻页 ] 行为.
此操作使视窗向右移动, 以便将可翻页控件右侧的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向左拖动视图.
- 新可视化内容: 右.
- 视窗移动方向: 右.
- 视图移动方向: 左.
[m=] pageDown#
pageDown()#
6.2.0
A11Y
API>=29
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗下移的翻页 ] 行为.
此操作使视窗向下移动, 以便将可翻页控件下方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向上拖动视图.
- 新可视化内容: 下.
- 视窗移动方向: 下.
- 视图移动方向: 上.
[m=] pressAndHold#
pressAndHold()#
6.2.0
A11Y
API>=30
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 按住 ] 行为.
按住即按下并保持, 与 ACTION_LONG_CLICK (长按) 不同.
如果控件的单一行为响应是为 "长按" 设计的, 则应该使用封装的 longClick 方法, 而非 pressAndHold 方法.
只有控件存在对 "按住" 行为的响应, 才会使 pressAndHold 有效.
通常控件不会同时存在上述两种行为的响应.
[m=] previousAtMovementGranularity#
previousAtMovementGranularity(granularity, isExtendSelection)#
6.2.0
A11Y
- granularity { number } - 粒度
- isExtendSelection { boolean } - 是否扩展选则文本
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 按粒度移至上一位置 ] 行为.
按指定粒度移动光标到上一个文本实体位置, 例如移动到上一个单词, 上一行, 上一个段落等.
const AccessibilityNodeInfo = android.view.accessibility.AccessibilityNodeInfo;
let w = pickup([ /.+/, { className: 'EditText' } ]);
/* 按 WORD (单词) 粒度移动. */
/* 除 WORD 外, 还支持 CHARACTER (字符), LINE (行), PARAGRAPH (段落), PAGE (页) 等粒度. */
w.previousAtMovementGranularity(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD, false);
[m=] previousHtmlElement#
previousHtmlElement(element)#
6.2.0
A11Y
控件节点执行 [ 按元素移至上一位置 ] 行为.
按指定元素名称移动焦点至上一元素位置, 例如移动到上一个按钮, 上一个列表, 上一个输入框等.
console.log(w.previousHtmlElement("BUTTON"));
[m=] showTextSuggestions#
showTextSuggestions()#
6.2.0
A11Y
API>=33
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 显示文本建议 ] 行为.
此操作将为一个可编辑文本的控件显示相关输入建议.
[m=] showTooltip#
showTooltip()#
6.2.0
A11Y
API>=28
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 显示工具提示信息 ] 行为.
此操作通常只对其视图未在显示工具提示信息的控件有效.
[m=] hideTooltip#
hideTooltip()#
6.2.0
A11Y
API>=28
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 隐藏工具提示信息 ] 行为.
此操作通常只对其视图正在显示工具提示信息的控件有效.
[m=] show#
show()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 显示在视窗内 ] 行为.
此操作使控件的所有边界全部出现在视窗内部.
如有需要, 页面会发生滚动.
/* "关于应用与开发者" 按钮部分 (或全部) 位于视窗外部. */
let w = pickup("关于应用与开发者");
if (w !== null) {
/* 控件将随着页面滚动到视窗内部. */
w.show();
}
[m=] dismiss#
dismiss()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 消隐 ] 行为.
检查一个控件节点是否可消隐:
console.log(w.dismissable());
console.log(w.isDismissable()); /* 同上. */
[m=] copy#
copy()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 复制文本 ] 行为.
此操作将控件的已选中文本内容复制到剪贴板.
[m=] cut#
cut()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 剪切文本 ] 行为.
此操作将控件的已选中文本内容剪切并置于剪贴板.
[m=] paste#
paste()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 粘贴文本 ] 行为.
此操作将剪贴板的文本内容粘贴到控件的可编辑文本区域.
需额外留意, 自 Android API 29 (10) [Q] 起, 剪贴板数据的访问将受到限制.
详情参阅 getClip.
[m=] select#
select()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 选中 ] 行为.
此操作将选中当前控件.
检查一个控件节点是否已被选中:
console.log(w.selected());
console.log(w.isSelected()); /* 同上. */
[m=] expand#
expand()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 展开 ] 行为.
此操作用于展开可展开的控件.
[m=] collapse#
collapse()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 折叠 ] 行为.
此操作用于折叠 (或收起) 可展开的控件.
[m=] scrollLeft#
scrollLeft()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗左移的滚动 ] 行为.
此操作使视窗向左移动, 以便将可滚动控件左侧的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向右拖动视图.
- 新可视化内容: 左.
- 视窗移动方向: 左.
- 视图移动方向: 右.
[m=] scrollUp#
scrollUp()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗上移的滚动 ] 行为.
此操作使视窗向上移动, 以便将可滚动控件上方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向下拖动视图.
- 新可视化内容: 上.
- 视窗移动方向: 上.
- 视图移动方向: 下.
[m=] scrollRight#
scrollRight()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗右移的滚动 ] 行为.
此操作使视窗向右移动, 以便将可滚动控件右侧的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向左拖动视图.
- 新可视化内容: 右.
- 视窗移动方向: 右.
- 视图移动方向: 左.
[m=] scrollDown#
scrollDown()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗下移的滚动 ] 行为.
此操作使视窗向下移动, 以便将可滚动控件下方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向上拖动视图.
- 新可视化内容: 下.
- 视窗移动方向: 下.
- 视图移动方向: 上.
[m=] scrollForward#
scrollForward()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗前移的滚动 ] 行为.
此操作使视窗向前移动, 以便将可滚动控件前方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向后拖动视图.
- 新可视化内容: 前.
- 视窗移动方向: 前.
- 视图移动方向: 后.
注: "前" 包括 "左" 或 "上", "后" 包括 "右" 或 "下".
[m=] scrollBackward#
scrollBackward()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 使视窗后移的滚动 ] 行为.
此操作使视窗向后移动, 以便将可滚动控件后方的更多内容 (如有) 展示在视窗内.
对于触屏设备, 此操作相当于按住屏幕并向前拖动视图.
- 新可视化内容: 后.
- 视窗移动方向: 后.
- 视图移动方向: 前.
注: "前" 包括 "左" 或 "上", "后" 包括 "右" 或 "下".
[m=] scrollTo#
scrollTo(row, column)#
A11Y
控件节点执行 [ 将指定位置滚动至视窗内 ] 行为.
此操作将集合中指定位置 (以 "行" 和 "列" 标记) 滚动至视窗内.
scrollable().find().some((w) => {
let info = w.getCollectionInfo();
if (info !== null) {
console.log(info.getRowCount()); /* e.g. 17 */
console.log(info.getColumnCount()); /* e.g. 2 */
let randRow = Mathx.randInt(info.getRowCount() - 1);
let randColumn = Mathx.randInt(info.getColumnCount() - 1);
console.log(`${randRow},${randColumn}`); /* e.g. 10,1 */
console.log(w.scrollTo(randRow, randColumn)); /* e.g. false */
return /* @some */ true;
}
});
[m=] contextClick#
contextClick()#
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 上下文点击 ] 行为.
此操作通常会弹出一个上下文菜单, 类似鼠标右键菜单.
注: 在 Microsoft Windows 操作系统中, 单击鼠标右键 (或按下键盘的菜单键) 即类似控件的 Context Click (上下文点击) 行为, 弹出的右键菜单又称为 Context Menu (上下文菜单).
[m=] setText#
setText(text)#
A11Y
控件节点执行 [ 设置文本 ] 行为.
此操作将使用新文本替换原有文本, 并将光标置于文本末尾.
let w = pickup({ className: 'EditText' });
/* 设置文本为 "hello". */
w.setText("hello");
/* 清空文本. */
w.setText("");
[m=] setSelection#
setSelection(start, end)#
A11Y
控件节点执行 [ 选择文本 ] 行为.
此操作将按指定范围选中控件的文本内容.
let w = pickup({ className: 'EditText' });
/* 选中 2 - 3 的 1 个文本, 起始光标停留在 2 位置, 末尾光标停留在 3 位置. */
w.setSelection(2, 3);
/* 无任何效果, 光标不发生变化. */
w.setSelection(2, 0);
w.setSelection(2, -5);
/* 抛出异常. */
w.setSelection(NaN, 0);
w.setSelection(Infinity, 0);
/* 选中 0 个文本, 此时起始和末尾两个光标重合. */
w.setSelection(2, 2);
[m=] clearSelection#
clearSelection()#
6.2.0
A11Y
- returns { boolean } - 是否行为已执行且执行过程中无异常
控件节点执行 [ 取消选择文本 ] 行为.
[m=] setProgress#
setProgress(progress)#
A11Y
控件节点执行 [ 设置进度值 ] 行为.
pickup({ action: ['SET_PROGRESS'] }, '[]').some((w) => {
const info = w.getRangeInfo();
if (info !== null) {
console.log(w.getMin(), w.getMax());
let randProgress = Mathx.randInt(w.getMin(), w.getMax());
console.log(randProgress);
console.log(w.setProgress(randProgress));
}
});
[I] ActionArgument#
控件的行为参数接口.
主要用于自定义控件行为的 performAction 抽象方法内.
[C] IntActionArgument#
ActionArgument 的具体类.
用于传递 Int 类型的行为参数.
[c] (name, value)#
- name { string } - 行为名称
- value { number } - 行为参数值
- returns { ActionArgument }
构造一个 Int 类型的行为参数.
/* 模拟 scrollTo 封装方法. */
function scrollTo(x, y) {
return w.performAction(
AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION.id,
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_ROW_INT, x),
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_COLUMN_INT, y),
);
}
[C] BooleanActionArgument#
ActionArgument 的具体类.
用于传递 Boolean 类型的行为参数.
[c] (name, value)#
- name { string } - 行为名称
- value { boolean } - 行为参数值
- returns { ActionArgument }
构造一个 Boolean 类型的行为参数.
/* 模拟 nextAtMovementGranularity 封装方法. */
function nextAtMovementGranularity(granularity, isExtendSelection) {
return w.performAction(
AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.id,
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, granularity),
ActionArgument.BooleanActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, isExtendSelection),
);
}
[C] CharSequenceActionArgument#
ActionArgument 的具体类.
用于传递 CharSequence 类型的行为参数.
[c] (name, value)#
- name { string } - 行为名称
- value { string } - 行为参数值
- returns { ActionArgument }
构造一个 CharSequence 类型的行为参数.
/* 模拟 setText 封装方法. */
function setText(text) {
return w.performAction(
AccessibilityActionCompat.ACTION_SET_TEXT.id,
ActionArgument.IntActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text),
);
}
[C] StringActionArgument#
ActionArgument 的具体类.
用于传递 String 类型的行为参数.
[c] (name, value)#
- name { string } - 行为名称
- value { string } - 行为参数值
- returns { ActionArgument }
构造一个 String 类型的行为参数.
/* 模拟 nextHtmlElement 封装方法. */
function nextHtmlElement(element) {
return w.performAction(
AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT.id,
ActionArgument.StringActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, element),
);
}
[C] FloatActionArgument#
ActionArgument 的具体类.
用于传递 Float 类型的行为参数.
[c] (name, value)#
- name { string } - 行为名称
- value { number } - 行为参数值
- returns { ActionArgument }
构造一个 Float 类型的行为参数.
/* 模拟 setProgress 封装方法. */
function nextHtmlElement(progress) {
return w.performAction(
AccessibilityActionCompat.ACTION_SET_PROGRESS.id,
ActionArgument.FloatActionArgument(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PROGRESS_VALUE, progress),
);
}
全局行为重定向#
本章节所有控件行为对应的方法 名称 均已全局化, 即支持 [ click()
/ paste()
/ scrollDown()
/ show()
] 等全局直接调用的方式来使用.
这些方法多数是 UiSelector 实例方法的直接绑定, 但有部分方法被 SimpleActionAutomator 覆盖.
下表列出了控件行为方法对应的绑定源.
其中 AUTO 代表 SimpleActionAutomator, SEL 代表 UiSelector.
Global Actions | AUTO | SEL |
---|---|---|
accessibilityFocus | √ | |
clearAccessibilityFocus | √ | |
clearFocus | √ | |
clearSelection | √ | |
click | √ | |
collapse | √ | |
contextClick | √ | |
copy | √ | |
cut | √ | |
dismiss | √ | |
dragCancel | √ | |
dragDrop | √ | |
dragStart | √ | |
expand | √ | |
focus | √ | |
hideTooltip | √ | |
imeEnter | √ | |
longClick | √ | |
moveWindow | √ | |
nextAtMovementGranularity | √ | |
nextHtmlElement | √ | |
pageDown | √ | |
pageLeft | √ | |
pageRight | √ | |
pageUp | √ | |
paste | √ | |
pressAndHold | √ | |
previousAtMovementGranularity | √ | |
previousHtmlElement | √ | |
scrollBackward | √ | |
scrollDown | √ | |
scrollForward | √ | |
scrollLeft | √ | |
scrollRight | √ | |
scrollTo | √ | |
scrollUp | √ | |
select | √ | |
setProgress | √ | |
setSelection | √ | |
setText | √ | |
show | √ | |
showTextSuggestions | √ | |
showTooltip | √ |
截至目前 (2022/11), 只有 [ click, longClick, scrollDown, scrollUp, setText ] 全局方法属于 SimpleActionAutomator.
copy(); /* 相当于 selector().copy(). */
paste(); /* 相当于 selector().paste(). */
clearFocus(); /* 相当于 selector().clearFocus(). */
imeEnter(); /* 相当于 selector().imeEnter(). */
click(1, 2); /* 相当于 automator.click(1, 2). */
longClick(1, 2); /* 相当于 automator.longClick(1, 2). */
setText("hello"); /* 相当于 automator.setText("hello"). */
scrollUp(); /* 相当于 automator.scrollUp(). */
scrollDown(); /* 相当于 automator.scrollDown(). */
通过 performAction 小节可知, UiSelector 的控件行为方法实际是对当前窗口中所有控件全部执行一次 Action, 因此几乎所有 UiSelector 的控件行为方法均不建议使用.
全局方法 paste 是使用率相对较高的控件行为, 且效果往往与预期相符.
有关全局方法 paste
的执行过程及原理分析可参阅 UiSelector#paste 小节.