似乎除了input type=password的edit text 其他所有的UI都可以进行操作。直接开始。

首先配置环境。

创建一个service 清单中代码如下,就算用AS直接创建,也需要配置一些权限等东西。

android:name=".MyAccessibilityService"

android:enabled="true"

android:exported="true"

android:label="@string/accessibility_service_label"

android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">

android:name="android.accessibilityservice"

android:resource="@xml/accessible_service" />

label 无障碍的名字,显示在系统辅助功能->无障碍界面的标题。权限不能掉,而且必须放在这。不能和其他权限一样放在上面。resource是无障碍服务的相关配置。xml文件如下:

//我直接写的注释 复制粘贴记得删除 不然会报错

xmlns:android="http://schemas.android.com/apk/res/android"

android:accessibilityEventTypes="typeAllMask"

android:accessibilityFeedbackType="feedbackGeneric"

android:accessibilityFlags="flagReportViewIds"

android:canRetrieveWindowContent="true"

android:notificationTimeout="100"

android:description="@string/description"//无障碍的文字描述,展示在系统设置界面

android:canPerformGestures="true"//允许模拟手势

android:packageNames="com.tencent.mobileqq"/>//要检测的窗口或应用的包名

各个属性的内容和含义看这个无障碍参数详情

然后新建一个MyAccessibilityService继承AccessibilityService

重写onAccessibilityEvent()和onInterrupt()

在onAccessibilityEvent()中操作,在检测到目标包名在前台运行的时候会回调这个方法,然后我们在这获取根视图。

try {

//拿到根节点

AccessibilityNodeInfo rootInfo = getRootInActiveWindow();

if (rootInfo == null) {

return;

}

//开始找目标节点,这里拎出来细讲,直接往下看正文

if (rootInfo.getChildCount() != 0) {

if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {

return;

}

//开始去找

findByID(rootInfo, "com.tencent.mobileqq:id/chat_item_content_layout");

}

} catch (Exception e) {

}

findByID方法如下:

private void findByID(AccessibilityNodeInfo rootInfo, String text) {

if (rootInfo.getChildCount() > 0) {

for (int i = 0; i < rootInfo.getChildCount(); i++) {

AccessibilityNodeInfo child = rootInfo.getChild(i);

try {

if (child.findAccessibilityNodeInfosByViewId(text).size() > 0) {

for (AccessibilityNodeInfo info : child.findAccessibilityNodeInfosByViewId(text)) {

performClick(getClickable(info));

//模仿全局手势

// performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS);

}

}

} catch (NullPointerException e) {

}

findByID(child, text);//递归一直找一层层的全部遍历

}

}

}

id通过DDMS看

有些控件处在listview或recyclerview下,就导致id重复,所以再用text匹配。

performClick(getClickable(info));这里的一个方法。

//有些节点不可点击 点击交给父级甚至父级的父级...来做的。

private AccessibilityNodeInfo getClickable(AccessibilityNodeInfo info) {

Log.i(TAG, info.getClassName() + ": " + info.isClickable());

if (info.isClickable()) {

return info;//如果可以点击就返回

} else {//不可点击就检查父级 一直递归

return getClickable(info.getParent());

}

}

此外通过文本内容来找到视图

private AccessibilityNodeInfo findByText(AccessibilityNodeInfo rootInfo, String text) {

if (rootInfo.getChildCount() > 0) {

for (int i = 0; i < rootInfo.getChildCount(); i++) {

AccessibilityNodeInfo child = rootInfo.getChild(i);

try {

if (child.findAccessibilityNodeInfosByText(text).size() > 0) {

for (AccessibilityNodeInfo info : child.findAccessibilityNodeInfosByText(text)) {

performClick(getClickable(info));

return null;

}

}

} catch (NullPointerException e) {

}

findByText(child, text);

}

}

return null;

}

找到了视图之后,就可以做各种动作,如输入框输入:

private void changeInput(AccessibilityNodeInfo info,String text) { //改变editText的内容

Bundle arguments = new Bundle();

arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,

text);

info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);

}

再如模拟手势:

private void MyGesture(){//仿滑动

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {

Path path = new Path();

path.moveTo(1000, 1000);//滑动起点

path.lineTo(2000, 1000);//滑动终点

GestureDescription.Builder builder = new GestureDescription.Builder();

GestureDescription description = builder.addStroke(new GestureDescription.StrokeDescription(path, 100L, 100L)).build();

//100L 第一个是开始的时间,第二个是持续时间

dispatchGesture(description, new MyCallBack(), null);

}

}

模拟手势监听的回调:

//模拟手势的监听

@RequiresApi(api = Build.VERSION_CODES.N)

private class MyCallBack extends GestureResultCallback {

public MyCallBack() {

super();

}

@Override

public void onCompleted(GestureDescription gestureDescription) {

super.onCompleted(gestureDescription);

}

@Override

public void onCancelled(GestureDescription gestureDescription) {

super.onCancelled(gestureDescription);

}

}

只是用无障碍可以实现点击 向上滑动 向下滑动,输入等等,左右滑动需要通过模拟手势来达到,但是模拟手势需要7.0+。

因为系统原因,无障碍服务每次运行完都得重新开启

快捷跳转 到无障碍设置界面

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);

startActivity(intent);

开启无障碍服务之后,再启动无障碍服务的Service

startService(new Intent(this, MyAccessibilityService.class));

无障碍服务基本可以捕捉所有界面并点击,包括6.0+弹窗授权。。。很是无语。

就到这吧 有啥不对的欢迎指出!

源码文件下载

模拟滑动android无障碍,Android无障碍简单开发-模拟滑动点击输入等相关推荐

  1. android有道词典简单开发

    Android剪切板(ClipBoardManager)复制的内容,可以粘贴到任何地方,对于一些词典,翻译工具等app具有较高的使用价值.有道词典在3.6版本后就使用到该功能,本文来剖析具体的实现过程 ...

  2. android蓝牙简单开发

    概述 前段时间学习了一些蓝牙开发的知识,记录一下Android中蓝牙的简单开发.下面是最重要的两个类. BluetoothAdapter : 蓝牙适配器,通过getDefaultAdapter ()去 ...

  3. Android 辅助功能(无障碍)自定义开发类似微信抢红包插件

    背景: 通常在无人值守的Android智能设备或不能触摸交互的设备中,当系统运行异常时, 系统有可能会弹出应用程序无响应(ANR)对话框,提示是否终止当前进程或等待,或应用程序异常退出时系统偶尔也会有 ...

  4. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件

    第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...

  5. 文件管理器android实现,Android开发之简单文件管理器实现方法

    易采站长站为您分析Android开发之简单文件管理器实现方法,简单实现了Android的文件目录查看,文件重命名,打开,删除等功能,需要的朋友可以参考下 本文实例讲述了Android开发之简单文件管理 ...

  6. android轮播图简单实现(左右无限滑动,自动轮播)

    直接上代码了,都有注释,原理很简单 public class MainActivity extends AppCompatActivity { private static final String ...

  7. 简单开发的android阅读器源码,包含了读取数据库和文件流处理功能

    原文:简单开发的android阅读器源码,包含了读取数据库和文件流处理功能 源代码下载地址:http://www.zuidaima.com/share/1838906559466496.htm 简单地 ...

  8. 【Android开发】Android Studio中进行简单的WebView构建浏览器开发1

    [Android开发]Android Studio中进行简单的WebView构建浏览器开发 第一步:新建一个Android Project 第二步:修改AndroidMainfest.xml文件 第三 ...

  9. 【Android开发】Android Studio中进行简单的WebView构建浏览器开发2

    [[Android开发]Android Studio中进行简单的WebView构建浏览器开发2 第1步:在上一篇博客的基础上,修改activity_main.xml 第2步:在MainActivity ...

最新文章

  1. 未比对上的bam reads 处理
  2. 高阶函数 实现sum(2)(3) 柯里化
  3. Spark常见问题解决办法
  4. 在Python当中如何打印输出当前时间(代码)
  5. linux 多线程基础2
  6. PyTorch学习—9.模型容器与AlexNet构建
  7. 服务器无法分配系统页面缓冲池中的内存
  8. 网络:bit、Byte、bps、Bps、pps、Gbps的单位详细说明及换算。
  9. 一键安装 kX3552 ProFX312 UFX52 程序
  10. 专访杨翰深先生 | Mockplus企业版为什么能获得贵州银行的青睐?
  11. 华为云influxdb+grafana+ prometheus安装和如何外网访问华为云+java环境安装配置+jmeter安装配置+Jmeter后端监听器+非GUI执行jmeter脚本
  12. 堕落了!经典软件下载网站被查
  13. python excel截图保存_如何用Python读取Excel中图片?又如何用Python往Excel中写入图片?...
  14. 阿里人绝不服输,用 7 部分讲明白百亿级高并发系统(全彩版小册开源
  15. 求逆序数-第12届蓝桥杯Scratch省赛3真题第3题
  16. Java和JDK版本的关系
  17. java list 子集_Java——List方法,获取子集
  18. selenium+python登录新浪微博
  19. HackTheBox::Optimum
  20. 小linux软件下载,超小的Linux发行版Puppy Linux 8.0发布下载

热门文章

  1. 绎维软件F-One获得B轮融资,华创资本领投,齐银基金跟投
  2. oracle从入门到跑路
  3. 使用与破解ExcelVBA密码
  4. OCR文本识别系统项目文档——欢迎探讨交流
  5. 【烈日炎炎战后端】消息队列(1.0万字)
  6. Web系统常见安全漏洞介绍及解决方案-sql注入
  7. 5月6日地图下载。同学们要练习!
  8. 如何在线对图片进行压缩?
  9. Layui官方js正则验证手机号,邮箱,网址,日期,身份证
  10. 快速把PDF文档里的表格粘贴到excel的方法