使用步骤

  1. 实现一个继承自 AccessibilityService 的服务类。
  2. 设定配置信息,以便系统知道该辅助模式的一些基本信息,例如监听那些事件。
  3. 在清单文件(AndroidManifest.xml)中,注册此服务。
  4. 在系统设置中,找到“无障碍”,并开启此服务。

1 继承 AccessibilityService

  1. public abstract void onAccessibilityEvent(AccessibilityEvent event);//监听的事件发生回调
  2. public abstract void onInterrupt();//系统事件被打断回调

2 配置辅助模式

配置 AccessibilityService 有两种方式,

  • 通过 xml 配置文件
<accessibility-servicexmlns:android="http://schemas.android.com/apk/res/android"android:accessibilityEventTypes="typeAllMask"android:accessibilityFeedbackType="feedbackAllMask"android:accessibilityFlags="flagReportViewIds"android:canRetrieveWindowContent="true"android:packageNames="com.forwarding.wechat"android:description="@string/accessbility_desc"android:notificationTimeout="100" />

accessibilityEventTypes:监听的事件类型,例如:typeAllMask 表示全部事件,而 typeViewClicked 表示只监听点击事件。
accessibilityFeedbackType:监听事件的反馈模式。
canRetrieveWindowContent:是否允许获取视图层级的访问权,如果它被设置为 false,node.getSource() 方法会调用失败。
accessibilityFlags:指定 Flag,一般用于指定根据 Node 获取 View ID 的权限。
packageNames:开启监听的应用包名,可以指定多个包名,通过逗号“,”分割,不设置此属性标识全局监听。
description:辅助功能的描述,它会显示在系统设置的“无障碍”中的描述信息中。
notificationTimeout:响应的毫秒数。

更多配置参数:https://developer.android.com/reference/android/accessibilityservice/AccessibilityService

  • 通过 Java 代码中动态配置。
    重写 AccessibilityService 的 onServiceConnected() 方法(不推荐)

3 清单文件中注册服务

<service android:label="无障碍名"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"android:name=".WeForwardServer"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService"/></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/accessibility_config"/>
</service>

4 开启辅助模式

默认为关闭状态,打开它的时候,你会收到一个警告弹窗,说明当前你正在开启一个无障碍的服务

编写逻辑代码

1 判断事件

  • eventType 判断事件类型(通过 eventType 来判断事件的类型,我们可以利用 getEventType() 方法获取到它。)
  • packageName 判断事件发生的 App(通过 getPackageName() 方法,判断出事件发生在那个 App 里的。)
  • className 判断当前发生事件的是那个类(通过 getClassName() 判断当前发生事件的是那个类)
  • text 判断当前事件触发源上的 Text(通过 getText() 获取当前事件源的 text 属性,可能是 TextView 的 Text,也可能是 Activity 的 Label 属性)

2 找到待控制的关键节点(Node)

通常我们是使用辅助模式去操作页面上的某个元素,那这一步,就是为了找到它。

在辅助模式下,页面上的每个元素,其实都是一个个 AccessibilityNodeInfo 节点,它是一个类似树形的结构,其内和我们真实 App 内的布局层级是一致的,但是并不能将它单纯的理解成一个 ViewTree。

既然是树形结构,我们首先要获取到根节点的 NodeInfo,可以通过以下两个方式获取:

event.getSource()
getRootInActiveWindow()

这两个方法都会返回一个 AccessibilityNodeInfo 对象。getSource() 是AccessibilityEvent 的方法,它可用的前提是前面配置 android:canRetrieveWindowContent 的时候,被设置为 True。所以我推荐使用 getRootInActiveWindow() 方法来获取。这两个方法还是略微有些差异,有兴趣可以打断点看看信息,但是大多数情况下,对我们使用者来说是一致的。

获得根节点的 AccessibilityNodeInfo 之后,就可以通过它找到我们想操作的关键节点,在 AccessibilityNodeInfo 中,提供了以下两个方法来找到关键节点。

findAccessibilityNodeInfosByViewId(String viewId)
findAccessibilityNodeInfosByText(String text)

一个是依赖 ViewId,另外一个是依赖 Text 信息。

使用 ViewId 查找关键节点是稳妥的方案,而使用 Text 去查找,可能会找不到。

无论通过哪种方式查找 关键节点 ,都是存在能找到多个 NodeInfo 的可能的,所以这两个方法干脆的都返回了一个 List ,所以需要我们通过其他条件再过滤一遍,通常就是通过 Text 信息过滤。

var mNodeInfo = rootInActiveWindow
var listItem = mNodeInfo.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/lp")
for (item in listItem) {if (item.text.toString().equals("承香墨影")){nodeClick(item)}
}

如果是使用 findXxxByText() 的方法的话,还需要注意它实际上不是通过类似 == 或者 equals() 的方法来查找子节点的,而是通过类似 contain() 的方式,所以只要节点的 text 属性包含查找的内容,都会被找到,这个我们额外还需要增加判断条件。

如果这些方法都试过,还是找不到关键节点,可以通过遍历的方式查找。

AccessibilityNodeInfo 既然是一个树状结构,也提供了我们遍历树的方法。

getParent():查找父节点。
getChild():返回子节点。
getChildCount():当前节点的子节点个数。
通过 getChild() 和 getChildCount() 两个方法,我们是可以对整个 ViewNodeTree 进行遍历,来找到我们关注的关键节点,这是一个最后的方案,并不推荐使用。

3 触发事件

辅助模式一般都是帮助我们响应一些事件,而这些事件大体上,可以分为两类。

  • 全局系统事件。
    对于全局系统事件,其实我们并不需要第二步找到的关键节点。AccessibilityService 提供了一个 performGlobalAction() 方法,我们可以通过该方法,操作一些全局的系统事件,例如:模拟返回键点击、模拟 HOME 键点击、锁屏等等。
// 返回键
performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
// HOME键
performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);

除了全局系统事件之外,通常我们就是想操作第二步拿到的关键节点。

在 AccessibilityNodeInfo 中,提供了一个 performAction() 的方法,可以通过该方法,对关键节点传递一个我们需要的事件。

这些事件都被定义在 AccessibilityNodeInfo 中,以 ACTION_ 为前缀定义。例如:ACTION_CLICK 是一个点击事件,ACTION_SET_TEXT 设置一个输入。

这里仅介绍一些比较常见的操作,更多的操作也是类似的使用方式。

  • View 事件。
    找到关键节点之后,就可以发送 AccessibilityNodeInfo.ACTION_CLICK 模拟对这个 View 的点击操作。
  1. EditText 输入文字
    对 EditText 输入文字,最少需要两个参数,关键节点和输入的文字。这就需要用到 performAction() 的另外一个重载方法,它允许额外在传递一个 Bundle 来指定参数。
private fun nodeSetText(node : AccessibilityNodeInfo?,text:String){var argument = Bundle()argument.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,text)node?.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT,argument)
}

所有支持定义的额外参数,都被定义在 AccessibilityNodeInfo 中,并以 ACTION_ARGUMENT_ 为前缀定义。
3. ListView 的滚动
AccessibilityNodeInfo 其实只能操作当前屏幕下可见的 节点,所以碰上 ListView 或者 RecycleView 这种列表,就需要对它进行滚动。

滚动的事件有两种:

  • ACTION_SCROLL_FORWARD
  • ACTION_SCROLL_BACKWARD
private fun nodeScrollList(node : AccessibilityNodeInfo?){node?.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)
}

一个前进一个后退,足够使用了。

4 回收资源

nodeInfo.recycle();

无障碍服务(AccessibilityService)相关推荐

  1. android accessibilityservice自动点击_【Android】无障碍服务(一)入门轻踩

    无障碍服务是一种应用,可提供界面增强功能,来协助残障用户或可能暂时无法与设备进行全面互动的用户完成操作.小编这边用无障碍服务实现一系列自动化操作,有点像按键精灵,踩了不少坑.首要部署声明才能被 And ...

  2. 通过AccessibilityService(无障碍服务)自动在设置界面打开App所需要的对应权限

    最近看到一个项目比如说需要允许访问应用权限.以及录屏等权限的时候 在手机运行的时候点击跳转至无障碍界面点击打开无障碍服务,然后调转至设置界面,然后手机就自动的一步一步的打开App所需的权限,看起来特别 ...

  3. Android 一文学会无障碍服务(AccessibilityService)

    什么是无障碍服务? 无障碍服务(AccessibilityService)是一套可以模拟操作的系统级别的API.用户同意我们的应用获取无障碍服务的权限之后就可以模拟操作,来控制用户的手机.无障碍被广泛 ...

  4. Android无障碍服务( Accessibility Service)应用

    无障碍服务是一个应用程序,它给有残疾的用户或暂时无法与设备完全交互的用户提供了更好的无障碍用户交互功能.比如驾驶.照顾小孩或者在吵闹的派对上可能需要额外或者替代的交互反馈. Android提供了标准的 ...

  5. 利用无障碍服务自动获取微信号

    利用无障碍服务自动获取微信号 前言 基本思路 过程 AccessibilityService是什么? 如何创建一个AccessibilityService? 如何开启AccessibilityServ ...

  6. Android实现自动点击 - 无障碍服务

    ps: 不想看代码的滑到最下面有apk包百度网盘下载地址 1. 先看效果图 不然都是耍流氓 2.项目目录 3.一些配置 build.gradle plugins {id 'com.android.ap ...

  7. Android 无障碍服务自动点击

    业余时间了解了Android无障碍服务的一些有趣功能,比如微信自动抢红包.应用宝的一键安装功能等.大致原理是监听手机窗体内容变化,拿到对应的View,进行点击.长按等Touch操作,下面我们就借助 A ...

  8. Android辅助功能(无障碍)使用---AccessibilityService

    参考资料:https://github.com/PopFisher/AccessibilitySample 1.Android文档里AccessibilityService简介 辅助功能只在帮助残障人 ...

  9. Android无障碍服务开发

    https://actionwind.wordpress.com/2022/04/17/android%e6%97%a0%e9%9a%9c%e7%a2%8d%e6%9c%8d%e5%8a%a1%e5% ...

最新文章

  1. spring的各种注解的作用-持续更新中
  2. IE 首页被改为www.1188.com的恢复办法
  3. 【JAVA SE】第五章 数组、多维数组和Arrays类
  4. java实验类与对象_【实验课件】上机实践2  类与对象
  5. LNMP Keepalived Haproxy 笔记
  6. matlab求解集合覆盖问题,Set Cover Problem (集合覆盖问题)
  7. AdvancedInstaller.com 命令行参数
  8. 将照片存入百度云人脸库
  9. 斗鱼实名认证 mysql_斗鱼新人主播怎么进行实名认证 斗鱼直播实名认证失败怎么办...
  10. 新世界日本语初级上(更新中)
  11. 《敏捷软件开发》— 敏捷开发 — 敏捷实践
  12. lzg_ad: FBWF技术概述
  13. 如何自学成为设计师_自学能成为一名平面设计师吗?如何提高审美?
  14. TOPSIS法笔记(优劣解距离法)
  15. 2023年留学生入户广州户口条件会有哪些
  16. 接手一个项目,后缀名为.bak文件,原来它是这个意思
  17. 通过慕课网学习Python
  18. 用户注册——注册信息保存到数据库
  19. 机器学习系列(14)_PCA对图像数据集的降维_03
  20. VoNR无线覆盖能力研究

热门文章

  1. 20190401每周精品之淘宝
  2. WebLogicServer BEA-000386 Weblogic启动报错
  3. UCK Network为区块链生态环境搭建一个完善自循环供水系统
  4. DAO跨事物调用---转账
  5. 一段话中手机号中间四位做特殊处理
  6. Java简单雷电游戏代码
  7. LaTeX排版(一):字体、页眉页脚、页边距、行距的设置
  8. Java项目酒店管理系统(java+SSM+Maven+LayUI+mysql)
  9. 杭电OJ1001 C
  10. 普宁市中学高考成绩查询2021,2021年揭阳高中录取分数线是多少及高中排名榜