Android辅助功能原理与基本使用详解-AccessibilityService

辅助功能原理与基本使用详解

本文主要介绍辅助功能的使用

辅助功能基本原理

辅助功能基本配置和框架搭建

辅助功能实战解析

一、辅助功能基本原理

辅助功能(AccessibilityService)其实是一个Android系统提供给的一种服务,本身是继承Service类的。这个服务提供了增强的用户界面,旨在帮助残障人士或者可能暂时无法与设备充分交互的人们。

从开发者的角度看,其实就是提供两种功能:查找界面元素,实现模拟点击。实现一个辅助功能服务要求继承AccessibilityService类并实现它的抽象方法。自定义一个服务类AccessibilitySampleService(这个命名可以随意),继承系统的AccessibilityService并覆写onAccessibilityEvent和onInterrupt方法。编写好服务类之后,在系统配置文件(AndroidManifest.xml)中注册服务。完成前面两个步骤就完成了基本发辅助功能服务注册与配置,具体的功能实现需要在onAccessibilityEvent中完成,根据onAccessibilityEvent回调方法传递过来的AccessibilityEvent对象可以对事件进行过滤,结合AccessibilitySampleService本身提供的查找节点与模拟点击相关的接口即可实现权限节点的查找与点击。

二、辅助功能基本配置和框架搭建

创建自定义辅助功能服务类

importandroid.accessibilityservice.AccessibilityService;

importandroid.view.accessibility.AccessibilityEvent;

importcom.accessibility.utils.AccessibilityLog;

publicclassAccessibilitySampleServiceextendsAccessibilityService{

@Override

protectedvoidonServiceConnected(){

super.onServiceConnected();

}

@Override

publicvoidonAccessibilityEvent(AccessibilityEventevent){

// 此方法是在主线程中回调过来的,所以消息是阻塞执行的

// 获取包名

StringpkgName=event.getPackageName().toString();

inteventType=event.getEventType();

// AccessibilityOperator封装了辅助功能的界面查找与模拟点击事件等操作

AccessibilityOperator.getInstance().updateEvent(this,event);

AccessibilityLog.printLog("eventType: "+eventType+" pkgName: "+pkgName);

switch(eventType){

caseAccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:

break;

}

}

@Override

publicvoidonInterrupt(){

}

}

注册辅助功能服务

// 注册辅助功能服务

android:label="@string/accessibility_tip"

android:exported="true"

android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"

android:process=":BackgroundService">

// 通过xml文件完成辅助功能相关配置,也可以在onServiceConnected中动态配置

android:name="android.accessibilityservice"

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

上面android:label="@string/accessibility_tip"是配置此辅助功能服务在系统辅助功能页面里面显示的名字。

accessibility_config文件内容如下:

android:accessibilityEventTypes="typeAllMask"

android:accessibilityFeedbackType="feedbackGeneric"

android:canRetrieveWindowContent="true"

android:description="@string/accessibility_desc"

android:notificationTimeout="100"/>

跳转到系统辅助功能页面,开启辅助功能服务

完成上面配置之后,辅助功能服务就注册成功了,在系统辅助功能页面就能找到这个服务,但是默认是关闭的,也就是说,这个服务要开始为我们服务,还需要去系统界面开启那个开关。下面是跳转到辅助功能页面的代码,跳转过去之后,手动点击开关按钮。开关打开之后,这个辅助功能服务就开始工作了,系统开始回调onAccessibilityEvent方法。我们可以在onAccessibilityEvent方法中处理查找节点与点击操作。

publicclassOpenAccessibilitySettingHelper{

privatestaticfinalStringACTION="action";

privatestaticfinalStringACTION_START_ACCESSIBILITY_SETTING="action_start_accessibility_setting";

publicstaticvoidjumpToSettingPage(Contextcontext){

try{

Intentintent=newIntent(context,AccessibilityOpenHelperActivity.class);

intent.putExtra(ACTION,ACTION_START_ACCESSIBILITY_SETTING);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent);

}catch(Exceptionignore){}

}

}

下图是小米手机开启辅助功能的界面

三、辅助功能实战解析

实现界面自动点击操作,动画有点模糊,将就看吧

界面节点查找与模拟点击

AccessibilityOperator封装了辅助功能的界面查找与模拟点击事件等操作,下面介绍几个关键的技术点。

界面节点查找操作

AccessibilityNodeInfo提供两种查找View节点的方法

1. 根据View的ID精确查找,但是要求SDK_INT >= 18才能用

/**

* 根据View的ID搜索符合条件的节点,精确搜索方式;

* 这个只适用于自己写的界面,因为ID可能重复

* api要求18及以上

* @param viewId

*/

publicListfindNodesById(StringviewId){

AccessibilityNodeInfonodeInfo=getRootNodeInfo();

if(nodeInfo!=null){

if(Build.VERSION.SDK_INT>=18){

returnnodeInfo.findAccessibilityNodeInfosByViewId(viewId);

}

}

returnnull;

}

2. 根据View的Text文本进行模糊查找

/**

* 根据Text搜索所有符合条件的节点, 模糊搜索方式

*/

publicListfindNodesByText(Stringtext){

AccessibilityNodeInfonodeInfo=getRootNodeInfo();

if(nodeInfo!=null){

returnnodeInfo.findAccessibilityNodeInfosByText(text);

}

returnnull;

}

模拟界面操作

1. 普通的View事件模拟(ACTION_CLICK)

privatebooleanperformClick(ListnodeInfos){

if(nodeInfos!=null&&!nodeInfos.isEmpty()){

AccessibilityNodeInfonode;

for(inti=0;i

node=nodeInfos.get(i);

// 获得点击View的类型

AccessibilityLog.printLog("View类型:"+node.getClassName());

// 进行模拟点击

if(node.isEnabled()){

returnnode.performAction(AccessibilityNodeInfo.ACTION_CLICK);

}

}

}

returnfalse;

}

2. 全局事件模拟(返回键:AccessibilityService.GLOBAL_ACTION_BACK)

publicbooleanclickBackKey(){

returnperformGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);

}

privatebooleanperformGlobalAction(intaction){

returnmAccessibilityService.performGlobalAction(action);

}

源码地址

https://github.com/PopFisher/AccessibilitySample

来源: http://www.cnblogs.com/popfisher/p/7455754.html

android 辅助功能原理,Android辅助功能原理与基本使用详解-AccessibilityService相关推荐

  1. Android异步处理三:Handler+Looper+MessageQueue深入详解

    本博文地址:http://blog.csdn.net/mylzc/article/details/6771331 转载请注明出处 Android异步处理系列文章索引 Android异步处理一:使用Th ...

  2. android setinputtype光标,Android屏蔽软键盘并且显示光标的实例详解

    Android屏蔽软键盘并且显示光标的实例详解 如果是android4.0以下,那么 editText.setInputType(InputType.TYPE_NULL); 就够了,android4. ...

  3. 关于android的4.2的0文件夹的详解

    关于android的4.2的0文件夹的详解 ---- android 4.0 ---- 在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd ...

  4. InheritableThreadLocal类原理简介使用 父子线程传递数据详解 多线程中篇(十八)...

    上一篇文章中对ThreadLocal进行了详尽的介绍,另外还有一个类: InheritableThreadLocal 他是ThreadLocal的子类,那么这个类又有什么作用呢? 测试代码 publi ...

  5. 生成jni的android.mk,Android Studio 3.5版本JNI生成SO文件详解

    学习在于记录,把自己不懂得容易忘记得记录下,才是最好得选择. 废话不多说,想要在Android开发中嵌入c/c++代码,直接开始如下步骤 1.创建需要调用的Java类 在你某个指定的包下创建如下类pa ...

  6. Android 系统(214)---Android 7.1.1时间更新NITZ和NTP详解

    Android 7.1.1时间更新NITZ和NTP详解 1.NTP和NITZ简介 最近在项目中遇到手机首次插上移动卡时不能自动更新时间的问题,就特意跟了下Android系统中手机时间更新有两种方式NT ...

  7. android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解

    android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解 1.下面的Xfermode子类可以改变这种行为: AvoidXferm ...

  8. 共模扼流圈的工作原理与作用以及特点和应用详解

    共模扼流圈的工作原理与作用以及特点和应用详解 - 电子常识 - 电子发烧友网 http://www.elecfans.com/dianzichangshi/20170609523118.html 共模 ...

  9. android代码查找快捷键是什么,Android Studio搜索功能(查找功能)及快捷键图文详解(示例代码)...

    1.在当前窗口查找文本[Ctrl+F] F3 向下查找关键字出现位置 Shift+F3 向上一个关键字出现位置 2.在当前工程内查找文本[Ctrl+Shift+F] 先会弹出一个对话框,直接点击[fi ...

最新文章

  1. ios开发ocr识别_车牌识别技术
  2. 栈——用顺序表实现栈操作
  3. Windows Phone开发(32):路径之PathGeometry 转:http://blog.csdn.net/tcjiaan/article/details/7469512...
  4. Svn服务器的搭建与配置
  5. java mysql ssl警告_连接到MySQL数据库时有关SSL连接的警告
  6. 求1到N的全排列 (转载)
  7. jQuery Mobile中翻转拨动开关slider的data-*选项
  8. 数据挖掘问题进行细分,主要分为哪四类问题
  9. java 的权限表_JAVA权限表
  10. seaweedfs java_seaweedfs-java-client
  11. 全国哀悼日,让网站全站变成灰色的CSS代码
  12. 霍乱时期的爱情——简写(下)
  13. 解决Connection error: (‘Unable to connect to any servers‘, {‘192.168.193.136‘: OperationTimedOut。。。。
  14. ALTAS,LAPACK, SCALAPACK, MUMPS记录
  15. 清空了回收站的文件还能找回吗
  16. 埃默里大学(Emory University)计算机系招收NLP方向博士生啦~
  17. CAN总线电容过大的有效解决方法
  18. JavaWeb项目中出现No converter found for return value of type的解决方法
  19. 把0到9的数字转换成电话按钮上的字母
  20. 计算机不认第二个硬盘,Windows 10无法识别第二个硬盘 | MOS86

热门文章

  1. 《安富莱嵌入式周报》第288期:微软推出Arm主控PC套件,WiFi信号捕获阵列,下一代雷电4技术,u-boot之父Wolfgang De离开了我们,向大神致敬
  2. 智慧兔哲理漫画《触摸你的温柔》
  3. 给8088单板机写一个迷你Boot
  4. CNN基础知识——池化(pooling)
  5. Python网络爬虫框架 Scrapy简介
  6. task07 类与对象、魔方方法
  7. 如何使用 Python 实现网页自动化朗读?
  8. 基于java的扫雷论文_毕业论文基于JAVA的扫雷游戏设计
  9. Python 实现「食行生鲜」签到领积分
  10. 【医生的黑色幽默】都是医生亲口说的