AccessibilityService 设计的目的就是帮助残障用户更好地使用手机,并希望开发者仅为了这个目进行开发。屏幕阅读器(Talkback)是正确用法的一个示范,点击屏幕后TTS语音读出触摸到的位置的内容,有视力障碍的用户就可以通过声音了解屏幕上发生了什么以及应该怎么操作。
中文互联网环境下,AccessibilityService 最常见的用法就是在抢红包,全自动化的流程比人类的反应快上不少,甚至曾经有些手机产商的系统就提供这种功能。虽然不是好的行为,但也是技术在生活中的一种应用。
AccessibilityService 还有很多奇特的用法,除了方便用户、让手机更好用之外,它还能让手机更难用。比如这个「格雷盒子」,使用 AccessibilityService 进行了自动化申请权限和修改系统设置,还能限制用户跳转到禁用的App中,实现了比较严格的家长控制功能。
AccessibilityService 是具有一定风险的功能,开启服务后用户隐私是根本无法保护的,用户收到的通知、屏幕上显示的大部分内容、各种输入框甚至未做特殊处理的密码输入框里的内容都可以完全静默获取。强烈建议非必须的功能不要通过AccessibilityService实现。
继承 AccessibilityService,自定义 Service
完善 AndroidManifest.xml 中的注册信息
custom_config.xml 的内容:
2. 筛选事件
事件回调是驱动 AccessibilityService 的核心,无障碍服务实现的难点之一是在众多事件中准确定位我们需要的那个 AccessibilityEvent。
区分事件的维度主要有以下几个:
通常需要结合多个参数的值才能确定事件的处理方式。
比较常见的 eventType 有这几个:
完整文档看这里:developer.android.google.cn/reference/k…
text 的内容是一个列表,内容包含 UI 显示的文本的时候可能被当前设置语言影响,使用 text 进行过滤的时候需要注意多语言的支持。
contentChangeTypes 仅在 eventType 为 TYPE_WINDOW_CONTENT_CHANGED 或者 TYPE_WINDOW_STATE_CHANGED 的时候有效,要注意返回的 Int 值是一个 bit mask。
对事件作出何种响应就由具体的需求决定了,当设置了 canRetrieveWindowContent 为 true 的时候,可以通过 或者 获取当前页面中的 AccessibilityNodeInfo 树的根节点。AccessibilityNodeInfo 节点与 View 树结构大致相同,找到需要的节点之后可以用 操作 View。
寻找需要的节点也是一个难点,AccessibilityNodeInfo 中提供了两个 find 方法简化调用代码: 和 。分别是通过 View 的 id 和 View 的 text 判断,返回值都是列表,之后还需要进一步判断。
View 之外的操作通过 调用,比如系统的虚拟导航操作或者物理键。目前 GlobalAction 有这些:
基于 View 体系的 AccessibilityNodeInfo 能进行的操作还是有限的,具体到点击某个 View 的某个区域或者从一个 View 的某一处开始滑动到哪里,就控制不了了。于是 API 24 之后增加了 函数实现完全的模拟用户手势操作。
的参数 GestureDescription 描述了一个手势操作,由一到多个 StrokeDescription 组成。每个 StrokeDescription 包含手势的 Path(没错,是我们熟悉的android.graphics.Path)、启动延迟时间和手势持续时间,组合这些参数可以实现相当复杂的轨迹绘制以及多点触控等精密操作。
效果图尺寸过大,可以复制链接查看:https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8f37c86efbcbbf2bedfd6288~tplv-k3u1fbpfcp-watermark.image
整个流程无手动控制。
有些手游有自律功能,但选择关卡和确认进入的地方还要用户操作,就是不支持自动连刷。AccessibilityService 可以帮助用户解放双手。
手游的页面是一整个 View,不能通过 AccessibilityNodeInfo 拿到任何有效信息。比较合理的解决方法是增加录屏功能,定期获取截取屏幕图像进行数字图像处理,通过某些特征值判断当前所在页面(比如缩放后使用预置特征区域截图进行模板匹配之类的)。
考虑到需要缩放,其实游戏的 UI 在适配了不同屏幕尺寸之后,一个按钮在屏幕里的相对位置是很固定的,所以直接通过按钮在屏幕中的相对位置划定区域,定时去点击对应区域也能满足需求。但缺点是稳定性差点,定时的延迟是固定的,中途被打断就难以恢复自动了。
录制了一段明日方舟经典关卡「主线1-7」的连刷视频,时间比较长,转成 gif 也有 70M+,只能上传视频了,点此跳转观看,由于是竖屏截图,效果不太好。
两个例子是写在一个项目中的,还在更新别的功能,项目中用到的技术点会随着使用整理发出,随缘更新。
以上内容只是 AccessibilityService 的一部分,如有错误欢迎评论指出。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/java-jiao-cheng/17715.html