安卓自动化之无障碍模式

查看 120|回复 9
作者:后脑i   

预计阅读时间5分钟
MIUI14更新后,李跳跳等工具便出现问题,为了满足使用的需求,便开始研究实现过程,下面是学习记录,解决方案请直接跳至第6点。

1.AccessibilityService无障碍服务

无障碍服务主要是用来协助残障用户更好的使用手机,但是各位大佬基于无障碍服务开发了很多玩法,例如抢红包、跳广告等,接下来我们新建个项目来实现跳广告功能。

1.1 创建服务
class MyAccessibilityService : AccessibilityService() {
    private val TAG = javaClass.simpleName
    override fun onAccessibilityEvent(event: AccessibilityEvent?) {
        Log.e(TAG, "onAccessibilityEvent$event")
        if (event?.eventType == TYPE_WINDOW_CONTENT_CHANGED) {
            if (event.className == "android.widget.TextView") {
                //获取跳过按钮并点击
                try {
                    val nodeInfo = rootInActiveWindow
                    if (nodeInfo != null) {
                        skip(nodeInfo, "跳过")
                    }
                } catch (e: Error) {
                    Log.e(TAG, "$e")
                }
            }
        }
    }
    /**
     * 匹配跳过规则
     */
    private fun skip(nodeInfo: AccessibilityNodeInfo?, str: String?) {
        val nodeInfoList = nodeInfo?.findAccessibilityNodeInfosByText(str)
        if (nodeInfoList == null || nodeInfoList.isEmpty()) {
            //页面跳转过程中,有可能获取不到
            return
        }
        for (info in nodeInfoList) {
            val charSequence = info.text
            if (charSequence != null) {
                val msg = charSequence.toString()
                if (msg.contains("跳过")) {
                    info.performAction(ACTION_CLICK)
                    Toast.makeText(this, "跳过广告", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
    override fun onInterrupt() {
    }
}
1.2配置服务
res目录下新建service_config.xml文件,名称可以自定义下一步会用到
1.3 添加清单文件
   
        
   

   
1.4 启动服务
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //跳转无障碍模式设置界面
    startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
}
2.实现无障碍功能

3.获取UI布局
3.1 findAccessibilityNodeInfosByText
在1.1中使用findAccessibilityNodeInfosByText来进行模糊匹配,为了满足精准匹配的需求,我们也可以通过获取id来实现(findAccessibilityNodeInfosByViewId)
3.2 findAccessibilityNodeInfosByViewId

使用uiautomatorviewer工具分析app界面
注:工具路径 在安卓sdk中 C:\Users\XX\AppData\Local\Android\Sdk\tools\bin\uiautomatorviewer.bat
运行的命令框请勿关闭


private fun skip(nodeInfo: AccessibilityNodeInfo?) {
    val nodeInfoList = nodeInfo?.findAccessibilityNodeInfosByViewId("com.moutai.mall:id/tvSkip")
    if (nodeInfoList == null || nodeInfoList.isEmpty()) {
        //页面跳转过程中,有可能获取不到
        return
    }
    for (info in nodeInfoList) {
        info.performAction(ACTION_CLICK)
        Toast.makeText(this, "跳过广告", Toast.LENGTH_SHORT).show()
    }
}
3.3 遍历父节点
通过获取父节点的AccessibilityWodeInfo,再通过该对象的getChild 方法来查询目标节点
private fun findInfo(
    info: AccessibilityNodeInfo?,
    str: String?,
): AccessibilityNodeInfo? {
    if (info == null) return null
    if (info.childCount == 0) {
        if (info.text!=null){
            if (info.text.toString().contains(str!!)) {
                info.performAction(ACTION_CLICK)
                Log.e("findInfo","$info")
            }
            return info
        }
    } else {
        for (i in 0 until info.childCount) {
            findInfo(info.getChild(i), str)
        }
    }
    return null
}
4.遇到的问题
4.1  android findAccessibilityNodeInfosByViewId return null although the node id exists
遇到这个问题时排查下获取nodeInfo是不是根活动视图,如果没有解决,再看下配置文件accessibilityEventTypes中的设置
最开始出现是使用event!!.source来获取,该方法是获取当前界面的可访问节点信息,但在跳转过程中有可能获取不到。
5.防范方式

1. 重写TextView的findViewsWithText方法
2. Event干扰
3. 使用onTouch代替onClick

6.MIUI14使用跳过功能
进入开发者选项--》启用MIUI功能--》关闭--》开启无障碍模式--》开启跳过广告的app--》重新启用MIUI功能
亲测使用正常!
以上就是无障碍服务的学习过程,如果有好的建议和想法可以留言或者私信,如果想深入了解可以访问官方文档,方便的话给个赞或者评分吧。

无障碍, 跳过

thatCbin   


丶汇梦 发表于 2023-2-15 15:00
李跳跳工具还有什么

看这个https://www.52pojie.cn/forum.php ... ;page=1#pid45382792
zhang7069   

实用技巧,已收藏
丶汇梦   

李跳跳工具还有什么
Pwaerm   


丶汇梦 发表于 2023-2-15 15:00
李跳跳工具还有什么

auto.js 也可以,但需要自己写脚本。
夏520   

现在的手机,无障碍服务都是不是长久开启的,重启手机或者过10分钟时间就自动关闭服务了,没得玩呢
j717013225   

很及时,我搞了好几次自动任务软件也没搞定,
dlovec   

学习基础知识  爱了
后脑i
OP
  


夏520 发表于 2023-2-15 15:51
现在的手机,无障碍服务都是不是长久开启的,重启手机或者过10分钟时间就自动关闭服务了,没得玩呢

是的,重启后基本上需要用户手动开启,根据不同的用户使用需求,可以采取后台保活的方式。
thatCbin   

比如视频中间暂停后出现广告也能实现关闭
您需要登录后才可以回帖 登录 | 立即注册

返回顶部