安卓无障碍API封装库:Android-Accessibility-Api (2.0)

Posted by Vove on February 16, 2022

接上篇:安卓无障碍API封装库: Android-Accessibility-Api

本次2.0更新带来了:

  1. 添加SmartFinder
  2. 支持多条件随意组合 搜索
  3. 支持条件扩展
  4. 协程支持

SmartFinder 介绍

1. 自定义条件搜索

搜索 AccessibilityNodeInfo.isChecked 为 true 的

1
2
3
4
//SF 为 SmartFinder缩写
SF.where { node ->
     node.isChecked
}.findAll()

2. 使用封装条件

搜索 id 为 text1 或者 text 为 “123” 的 Node

1
SF.id("text1").or().text("123").findAll()

3. 复杂条件搜索

(text=="111" && desc=="111") || (text=="222" && desc=="222")

1
2
3
SF.where(SF.text("111").desc("111"))
    .or(SF.text("222").desc("222"))
    .findAll()

4. 其他搜索方式

提供了中缀表达式,支持属性 _text, _desc, _id

1
2
3
4
5
6
7
8
9
SF.and(_text contains "Smart").clickable().findFirst()

SF.where(_id eq "view_id").findFirst()
//等效
SF.id("view_id").findFirst()

//使用中缀表达式
(SF where text("1111") or text("2222")
        and id("111") or longClickable()).findAll()

5. 协程支持

支持协程主要是为了在等待搜索时,能够及时响应 Job.cancel()

1
2
3
4
//主动附加协程上下文,可在搜索时感知取消事件
SF.attachCoroutine()
    .id("view_id")
    .waitFor(10_000)

扩展搜索条件

封装自定义搜索条件,使调用起来更简洁 库中搜索条件全部实现位于 SmartFinderConditions.kt

例如 定义使用正则匹配Node文本

Step 1.
1
2
3
4
5
6
7
8
class TextMatcherCondition(private val regex: String) : MatchCondition {
	//此处注意直接创建Regex,防止在搜索时重复创建;另外可直接检查正则表达式有效性
    private val reg = regex.toRegex()
    override fun invoke(node: AcsNode) =
        node.text?.toString()?.let {
            reg.matches(it)
        } ?: false
}

此时,已经可以这样使用:

1
SF.where(TextMatcherCondition("[0-9]+")).findAll()

追究简洁,可进行扩展方法:

Step 2.
1
fun ConditionGroup.matchText(reg: String) = link(TextMatcherCondition(reg))

之后可简化调用

1
SF.matchText("[0-9]+").findAll()

Github =>