• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

(AccessibilityService)Android辅助功效条记

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0918/646.html

 
近来由于常州软件技术培训项目的需要(在某个界面需要自动的点击某个按钮),以是打仗了关于辅助功效的开辟。刚首先的时分基础没有想到能够用辅助功效来赞助实现这个需要,连续在看关于屏幕监听和模仿点击的少许材料。后来经历有经验的同事的介绍,发现能够使用辅助功效来实现我这一需要。话未几说,首先介绍这个辅助功效(AccessibilityService):
 
1. 建立本人的辅助功效类:
编写本人的服无类,需要秉承AccessibilityService类。
 
对于少许需要重载的方法的介绍:
 
onServiceConnected();
 
体系会在胜利连接上你的服无的时分调用这个方法,在这个方法里你能够做一下初始化事情,例如建筑的声响触动经管,也能够调用setServiceInfo()进行配置事情。
 
onAccessibilityEvent();
 
经历这个函数能够汲取体系发送来的AccessibilityEvent,汲取来的AccessibilityEvent是经由过滤的,过滤是在配置事情时设置的。
 
onInterrupt();
 
这个在常州平台运营体系想要中缀AccessibilityService返给的响应时会调用。在全部性命周期里会被调用屡次。
 
onUnbind(Intent intent);
 
在体系将要封闭这个AccessibilityService会被调用。在这个方法中进行少许开释资源的事情。
 
1.1 配置:
对于辅助功效类的配置有两种方法:
 
(1)onServiceConnected()中初始化的方法:
 
 
配置service_info
(2)使用在manifest中增加meta-data的方法(Android 4.0 首先 ——能够拜见我在注册中的代码片断)
 
在value文件夹中,增加一个xml文件夹(名字应该是能够自定义的,个人没有试过),并在其中增加一个accessibilityservice.xml大约任何你稀饭的名字。可拜见下图:
 
 
配置service_info
建议将少许不可动静变动的服无配置写到xml文件中。
 
能够看到上边使用了片面的参数,都是对照常用的少许参数配置,底下来介绍下这些参数的用途:
 
Event types(android:accessibilityEventTypes  /  info.eventTypes)
 
简单说两个常用的:(详细的能够参照API真的太多了)
 
typeAllMask  /  AccessibilityEvent.TYPES_ALL_MASK:全局事件响应
 
typeViewClicked  /  AccessibilityEvent.TYPE_VIEW_CLICKED :点击事件
 
Feedback Types(android:accessibilityFeedbackType  /  info.feedbackType )
 
feedbackGeneric  /  AccessibilityServiceInfo.FEEDBACK_GENERIC : 通用的反应
 
feedbackAudible  /  AccessibilityServiceInfo.FEEDBACK_AUDIBLE : 声响反应
 
feedbackSpoken  /  AccessibilityServiceInfo.FEEDBACK_SPOKEN  :  常州微信公众平台语音反应
 
CanRetrieveWindow  (android:canRetrieveWindowContent  /info.getCanRetrieveWindowContent())
 
从一个AccessibilityEvent中观察彻底视图层级的才气隐式地露出私有用户信息给你的无障碍服无。出于这个缘故,你的服无必需经历无障碍服无配置XML文件要求这个级别的走访权,经历包含canRetrieveWindowContent属性和设置它为true。要是你不在你的服无配置xml文件中包含这个设置,辣么对getSource()的调用会失利。
 
PackageNames (android:packageNames=  /  info.packageNames)
 
需要服无监听的包名,中间能够用","分开开。
 
notificationTimeout(android:notificationTimeout  /  info.notificationTimeout)
 
响应光阴的设置
 
1.2 Service类中对事件的阻挡处理
这个片面要紧在onAccessibilityEvent()中处理回调返回的AccessibilityEvent。
 
要紧需要打听的有:
 
AccessibilityNodeInfo(findAccessibilityNodeInfosByViewId,findAccessibilityNodeInfosByText)
 
AccessibilityEvent(eventType)
 
(1)AccessibilityEvent:
 
首先常州微信小程序开发介绍AccessibilityEvent:
 
This class represents accessibility events that are sent by the system when something notable happens in the user interface.(在用户交互使用时体系返回的event事件)
 
方法:
 
getSource() :
 
Gets the AccessibiltyNodeInfo of the event source.
 
目前event的节点信息
 
趁便说下getRootInActiveWindow()
 
Gets the root node in the currently active window if this service can retrieve window content.
 
中文的翻译应该是获得到目前活跃中本服无的可检索到窗口的根节点
 
getSource()  大约即是? AccessibilityService.getRootInActiveWindow();(我输出过两个NodeInfo的child个数,不太一致,有个数差。)
 
It is a client responsibility to recycle the received info by calling AccessibilityNodeInfo.recycle() to avoid creating of multiple instances.
 
为幸免建立重叠的实例经历recycle方法接管掉nodeInfo(咱们本人手动去接管)
 
eventType :(常用)
 
TYPE_NOTIFICATION_STATE_CHANGED
 
represents the event of change in the content of a window. This change can be adding/removing view, changing a view size, etc.
 
根基窗口view的变更都能够使用这个type来监听
 
TYPE_WINDOW_STATE_CHANGED
 
Represents the event of opening a Pop,Menu,Dialog etc.
 
翻开popupwindow,菜单,对话框时分会触发
 
TYPE_WINDOW_CONTENT_CHANGED
 
Represents the event of changing the content of a window and more specifically the sub-tree rooted at the event's source.
 
加倍精确的代表了基于目前event.source中的子view的内容变更
 
TYPE_WINDOWS_CHANGED
 
Represents the event change in the windows shown on the screen.
 
窗口的变更
 
AccessibilityEvent
 
(2)AccessibilityNodeInfo:
 
我以为是辅助功效中非常紧张的的一个内容,也是非常坑的地方到来了。
 
关于节点这个题目应该是没有太多的可说的地方,但是呢,出题目出的至多的地方也是这里。
 
先看下怎么获得NodeInfo:
 
AccessibilityNodeInfo mNodeInfo = getRootInActiveWindow();
 
AccessibilityNodeInfo mNodeInfo= event.getSource();
 
两种获得方法,之前我也提过,偶然候两种方法获得的childNode个数不一致,挨了个球,我都不晓得是肿么回事,有打听道理的大大请给我解解惑吧。
 
好的接下来咱们来查找咱们需要做操纵的view,在NodeInfo中,默认提供了两个方法来查找咱们需要操纵的对象:(首先重头戏)
 
findAccessibilityNodeInfosByViewId(String str)
 
findAccessibilityNodeInfosByText(String str)
 
(1)先说上一个方法:findAccessibilityNodeInfosByViewId(String id)
 
List <AccessibilityNodeInfo> listNodes = mNodeInfo.findAccessibilityNodeInfosByViewId("id");
 
好的,关于这个ID我真的想说说事,每个API不同,同一个对象的ID大约不同:So,做国外化的时分,恶梦来了,为何在大Samsung上边能够找到并操纵这个node对象,在LG上就不能够捏....
 
OK,这里就来到了咱们的关于node对象的id题目了,宁神,Google会让你有办理方法的。(但是即是要累死你,累死你累死你)谨慎的来到Hierarchy View。(这里能够百度,大约即是在Android Device Monitor中翻开这个View,查看对应界面的view的ID信息)。
 
关于真机不行连接Hierarchy View,能够看下我另一篇文章《AccessibilityService 获得View的Id》
 
 
好了,几何同窗以为晓得id就完了,呵呵,too young to naive。
 
id的花样大约是这样的"com.android.settings:id/force_stop_button"(这里以设置界面的强迫休止按钮作为对照),请留意加粗的片面,WTF我怎么晓得这个前边是神马...
 
不要惊慌,留意看这里:
 
 
伶俐的小身边的人打听了吧。哈哈未几说,没懂就多看看图。
 
(2)说完了findById,咱们接着说findAccessibilityNodeInfosByText(String text)
 
List listNodes = mNodeInfo.findAccessibilityNodeInfosByText("text");
 
看了常州网站开发建设上边的findById以后,这个方法也简单多了吧。没有辣么坑,只是做中文体系的时分,干脆就能够看图写环节词。以是就未几说了。
 
(3)关于node的使用:
 
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
 
点击事件简单至极,一看就清晰了。
 
需要其余的操纵,只需要看看API,换换ACTION啦。
 
(4)全局按钮的操纵
 
performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
 
同上。全局的操纵是在service做出的action,和node没有太大的关系。
 
2. 注册:
AccessibilityService,从名字上来看,有经验的小身边的人就不丢脸出来,他是一个service,(心里独白:屁话,是个猿都能看出来,鄙视...)那对于他的注册,就不需要多说了,这里扼要的将manifest中service注册的少许参数做出分析:
 
 
name:对应的是自定义service的包名
 
label:对应了在体系辅助功效开关界面中,你的service的名字(例如:手机管家等)
 
description :则是点击对应的服无进来开关界面后,该服无的简介
 
permission:应该都不目生,对应的权限
 
(亦可在service中独自写出来
 
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE">)
 
intent-filter:指定了实行的组件为辅助功效类
 
3. 其余的少许辅助校验的方法:
3.1是否开启辅助功效的校验
 
3.2 跳转到辅助功效界面,开启辅助功效
 
总结:
在辅助功效开辟中,首次开辟的身边的人大约会碰到的少许难点(我以为我第一次开辟的时分非常可贵即是找viewId)
 
1、获得需要操纵的viewId
 
之前也提到过能够使用hierarchy View来查找对应的viewId,但是在现实开辟中,许多手机是没有办法连接server进行dump view的,在这个时分,咱们实在能够在AccessibiltiyService的配置中增加一个flag。对应的属性是:android:accessibilityFlags="flagReportViewIds"。在代码中咱们就能够经历node节点来getViewIdResourceName()获得对应的节点的id。
 
2、获得到id后,查找到需要操纵的node
 
凭据id查找节点的方法上边也有介绍过,需要留意的是,id的花样,对于packageName咱们能够经历getPackageName()方法获得。
 
非常后,祝大家都能够兴奋的进行辅助功效的开辟事情。
 
PS.在网上搜刮辅助功效的话,都会发现少许关于微信抢红包的插件。没错,微信抢红包的插件即是使用了游戏开发运营咱们今天要介绍的辅助功效来开辟的。
 

上篇:上一篇:Android AccessibilityService应用留意
下篇:下一篇:Android 获取Device Id