当前位置: 首页 > news >正文

Android辅助功能(Accessibility)简介

Accessibility

由于部分安卓用户在身体的问题致使他们不能看完整的屏幕或者使用触屏,google提供了Accessibility功能和服务帮助这些用户更加简单地操作设备。这其中最主要的一个类就是AccessibilityService,AccessibilityService是一个系统服务,它运行在后台,并且能够收到由系统发出的一些事件,比如通知状态、按钮被点击了等等。界面中产生的任何变化都会由系统通知给AccessibilityService.这就像监视器监视着界面的一举一动。

AccessibilityService生命周期

AccessibilityService继承了service,他是在后台运行的。

1、AccessibilityService是系统服务,该服务完全由系统管理,并遵循已有的服务周期.

2、开启一个服务只能由用户在设置中打开,而关闭则只能由用户在设置中关闭或者服务本身通过diableSelf()方法关闭

3、系统绑定该服务之后,会调用onServiceConnected()方法,这个方法可以被重写,在这里可以做一些初始化的操作.

4、在实际的操作实验中发现,即便手动开启该服务,在6.0以上的系统经过一段时间也会自动关闭。

在实际开发中,可以继承AccessibilityService类,然后有选择的实现其中的一部分函数,就可以实现一些特殊的功能。

AccessibilityService函数

1.onAccessibilityEvent(AccessibilityEvent event

)必须重写。AccessibilityEvent是一个事件类,里面封装了许多字段,表示各种不同的事件(通知、窗口内容)。形参event表示事件变化,接收来的AccessibilityEvent是可以经过过滤的,过滤是在配置工作时设置的。 

2.onInterrupt()必须重写。这个在系统想要中断AccessibilityService返给的响应时会调用。在整个生命周期里会被调用多次。

3.onServiceConnected()可选。在系统成功连接上这个AccessibilityService会调用。在这个方法里主要做初始化工作。

4.onUnbind()可选。在系统将要关闭这个AccessibilityService会被调用。在这个方法中主要做释放资源的工作。

声明

AccessibilityService和在menifest中声明其他service一样,但要额外做两件事

1.配置<intent-filter>,其name为固定的

2.声明BIND_ACCESSIBILITY_SERVICE权限,

<service
    android:name=".AutoReplyService"
    android:enabled="true"
    android:exported="true"
    android:label="@string/app_name"
  android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService"/>
    </intent-filter>
</service>

配置

AccessibilityService可以添加一些配置信息,目的是只接收一些特定的事件.例如:监听特定的包、android给我们提供2种配置方法:

方法1:meta-data标签方式:

在manifest声明的servce中提供一个meta-data标签,然后通过android:resource指定相应的配置文件(在res目录下创建xml文件,并在其中创建配置文件accessibilityservice.xml):

<meta-data
    android:name="android.accessibilityservice"
    android:resource="@xml/auto_reply_service_config"/>

方法2:调用setServiceInfo(AccessibilityServiceInfo)方式:AccessibilityServiceInfo用于配置AccessibilityService信息,类中包含了大量用于配置的常量字段。

1.这个方法可以在任何时候调用,动态的去改变service配置信息

2.这个方法只能用来配置动态属性,如:eventTypes,feedbackType,flags,notificationTimeout等。

通常是在onServiceConnected()进行配置

启动服务

当我们配置完成,进行运行后就可以安装到手机.安装成功后,在设置->辅助功能中便可以找到我们的服务.该服务默认处在关闭状态,需要手动开启.

获取界面指定控件

Android中的View体系是一个树形结构,所以每一个View就是一个节点。安卓系统提供了两个方法让我们来进行查找想要的节点View

第一种是通过节点View的Text内容来查找

findAccessibilityNodeInfosByText("查找内容") 这种方式查找,对于有文本内容的哪些控件,可以使用这种方式快速的找到。

第二种是通过节点View在xml布局中的id名称

findAccessibilityNodeInfosByViewId("@id/xxx")我们可以通过HierarchyView查找指定控件的id,

模拟点击

在找到指定的View节点,调用方法模拟事件:

performAction(AccessibilityNodeInfo.ACTION_CLICK)调用这个方法,AccessibilityNodeInfo类中封装了与控件有关的相关字段和方法,这里的参数就是指定事件的名称,这个和AccessibilityEvent中监听的那些事件是一一对应的,这里是模拟点击事件,同理也可以模拟View的滚动事件,长按事件等。

实例

QQ自动回复:实现QQ自动回复,其实就是监听QQ的包名以及通知变化,当QQ来消息的时候,自动跳到聊天界面,填充消息并点击发送。(类似于自动化测试)

具体步骤:

1.      监听QQ发出的Notification,此时要判断是否锁屏状态

2.      点击Notification的contentIntent属性,进入到QQ详情页

3.      从根节点开始,查找指定的edittext,并进行内容填充。

5. findAccessibilityNodeInfosByText(发送)

调用performAction(AccessibilityNodeInfo.ACTION_CLICK)实现模拟点击

总结一下,辅助功能的大概思路

第一、有选择的监控界面变化,并进行通知,有需要的进行跳转

第二、当有event发生时,寻找到我们想要的View节点

第三、模拟操作,实现特定功能

坑点

1.包被混淆,之前通过AndroidDevice Monitor查看ID,然后根据findAccessbilityNodeInfoById ()去匹配节点,包被混淆之后每个版本不一样

2.很难找出没有文本的控件,如EditText,ImageView

3、部分手机在手动开启一段时间后自动关闭,导致部分功能不稳定。

4、对于有手机锁屏密码的无法打开其屏幕

用途:

辅助功能还可以进行一些其他的功能:

1、  微信抢红包:监听微信红包,当收到红包时,自动模拟点击

2、  强制停止应用:我们可以监听系统的应用详情页面,然后找到:结束运行的节点View,然后模拟点击即可

3、  检测自己的app是否在前台。

相关文章:

  • SSM网约车管理系统毕业设计-附源码051630
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • 第11章Linux实操篇-Linux磁盘分区、挂载
  • Kotlin协程:Flow的融合、Channel容量、溢出策略
  • android毕业设计选题基于Uniapp+SSM实现的互联网云数据环境下的供销APP购物商城电商
  • 超级详细的mysql安装和配置教程
  • 超级详细的Maven使用教程
  • 界面组件DevExpress WPF Data Grid哪些功能还能增强?一起来看
  • 爱上开源之golang入门至实战第四章函数(Func)(十)
  • SQL Dblink SQL
  • 超级无敌详细使用ubuntu搭建hadoop完全分布式集群
  • Flink学习22:窗口的划分
  • 【卫朋】产品管理:如何做缺陷(漏洞)管理?
  • 第11讲:DQL数据查询语句综合案例实战
  • PostgreSQL中的技术内幕
  • 【347天】每日项目总结系列085(2018.01.18)
  • Bootstrap JS插件Alert源码分析
  • Docker下部署自己的LNMP工作环境
  • Git同步原始仓库到Fork仓库中
  • linux安装openssl、swoole等扩展的具体步骤
  • maven工程打包jar以及java jar命令的classpath使用
  • Sublime Text 2/3 绑定Eclipse快捷键
  • XML已死 ?
  • 跨域
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • gunicorn工作原理
  • 阿里云服务器如何修改远程端口?
  • (2)STL算法之元素计数
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (ZT)一个美国文科博士的YardLife
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (七)c52学习之旅-中断
  • (三) diretfbrc详解
  • (转)Unity3DUnity3D在android下调试
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .apk 成为历史!
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET/C# 的字符串暂存池
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • [20160902]rm -rf的惨案.txt
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [C#]winform制作圆形进度条好用的圆环圆形进度条控件和使用方法
  • [Design Pattern] 工厂方法模式
  • [ERROR] 不再支持目标选项 5。请使用 7 或更高版本
  • [GXYCTF2019]BabySQli1
  • [HDU] 1054 Strategic Game 入门树形DP
  • [hive小技巧]同一份数据多种处理
  • [Java][Android][Process] 暴力的服务能够解决一切,暴力的方式运行命令行语句
  • [Java][方法引用]构造方法的引用事例分析
  • [java基础揉碎]关系运算符(比较运算符)逻辑运算符赋值运算符三元运算符运算符的优先级