熟悉Android开发的都知道辅助功能服务 Accessibility service。他的作用有非常多。360豌豆荚等应用市场的非root自己主动安装。微信抢红包插件。盲人辅助程序等等功能都是靠它实现的。 网上关于AccessibilityService的阐述和使用方法已经非常多非常具体了。能翻墙且英文没问题就直接看官网:http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html这里介绍个模拟自己主动点击事件的流程。

附上demo: https://github.com/jackuhan/WeChatLuckyMoney

我们写一个继承自AccessibilityService的XXXService类。在manifest中注冊下

<service
android:name=".XXXService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/accessible_service_config"/>
</service>

这里注冊了响应AccessibilityService 的intent-filter,那么这个service能够在系统触发AccessibilityEvent的时候被回调到。这个时候你的service此时会响应全部应用的同类Event,假设想仅仅响应某个特殊应用就须要使用setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo),这个须要在

onServiceConnected() 的回调中设置。

@Override
public void onServiceConnected() {
info.eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED | AccessibilityEvent.TYPE_VIEW_FOCUSED;
info.packageNames = new String[] {"com.example.android.myFirstApp", "com.example.android.mySecondApp"};
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
info.notificationTimeout = 100;
this.setServiceInfo(info);
}

在程序中推断有没有开启这个自己主动点击服务。

AccessibilityManager accessibilityManager = (AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE);
List<AccessibilityServiceInfo> accessibilityServices = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
for (AccessibilityServiceInfo info : accessibilityServices) {
if (info.getId().equals(getPackageName() + "/.XXXService")) {
//开启了服务
}
}

假设没有开启。那么打开系统设置页面,用户点击开启。

Intent mAccessibleIntent =  new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(mAccessibleIntent);

AccessibilityService有下面几个回调

public void onAccessibilityEvent(AccessibilityEvent event);
public void onInterrupt();
public void onServiceConnected();
public void init(int connectionId, IBinder windowToken);
public boolean onGesture(int gestureId);
public boolean onKeyEvent(KeyEvent event);

onServiceConnected ()方法是AccessibilityService声明周期的一部分。在系统成功与服务绑定后才被呼叫,假设用来设定AccessibilityServiceInfo.这种方法更为方便。

这里须要在onAccessibilityEvent的回调中得到AccessibilityEvent ,

通过AccessibilityEvent.getSource()方法可以从资源中获得窗体的内容和行为,AccessibilityNodeInfo。通过findAccessibilityNodeInfosByViewId()或者findAccessibilityNodeInfosByText()方法可以确定我们要点击的button;

,然后performAction  ACTION_CLICK就可以就完毕了点击名称为"Name"的控件的事件了。

onAccessibilityEvent(AccessibilityEvent event)  {
AccessibilityNodeInfo nodeInfo = event.getSource()
List<AccessibilityNodeInfo> fetchNodes = nodeInfo.findAccessibilityNodeInfosByText("Name");
AccessibilityNodeInfo openNode = fetchNodes.get(int i);
openNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}

Android 4.0版本号中添加了一个新特性,就是可以用AccessibilityService来遍历View层级。并从产生Accessibility 事件的组件与它的父子组件中提取必要的信息。为了实现这个目的,你须要配置:android:canRetrieveWindowContent="true"。

同一时候Android 4.0版本号開始,可以使用XML文件来配置这类service。

格式例如以下所看到的:

<accessibility-service
android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity"
android:canRetrieveWindowContent="true"
/>

假设你使用了xml配置service的方式。确保在manifest中声明 <meta-data>这个标签内容。指定该service保存在res/xml/serviceconfig.xml中,比如这样:

<service android:name=".MyAccessibilityService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/serviceconfig" />
</service>

Accessibility辅助控制类的更多相关文章

  1. .net之工作流工程展示及代码分享(四)主控制类

    现在应该讲主控制类了,为了不把系统弄得太复杂,所以就用一个类作为主要控制类(服务类),作为前端.后端.业务逻辑的控制类. WorkflowService类的类图如下: 该类的构造函数: public ...

  2. PHP-权限控制类

    http://blog.csdn.net/painsonline/article/details/7183679 <?php /** * 权限控制类 */ class include_purvi ...

  3. 类型转换辅助工具类TypeCaseHelper

    package org.sakaiproject.util; import java.math.BigDecimal; import java.sql.Date; import java.sql.Ti ...

  4. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  5. Day 5-8 自定义元类控制类的实例化行为

    __call__方法: 对象后面加括号,触发执行. 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类( ...

  6. 【HLSDK系列】服务端实体 edict_t 和 控制类

    我们来了解一下引擎是怎么管理实体的吧!我们这里就说说服务端的实体(edict_t) 服务端用 edict_t 这个结构体来保存一个实体,可以说一个 edict_t 就是一个 服务端实体,下文简称实体. ...

  7. PHP-权限控制类(转)

    <?php /** * 权限控制类 */ class include_purview { /** * 类的唯一实例 */ private static $instance; /** * 权限常量 ...

  8. scratch教程:学做控制类积木

    少儿编程中scratch很容易被小孩所接受,不管是从外观还是教程中,都符合少儿的兴趣,为此现在只要是开少儿编程课都会有scratch课程,今天娜娜姐小码王scratch培训机构就为大家分享,scrat ...

  9. java多线程(六)线程控制类

    1.   多线程控制类 为了保证多线程的三个特性,Java引入了很多线程控制机制,下面介绍其中常用的几种: l  ThreadLocal l  原子类 l  Lock类 l  Volatile关键字 ...

随机推荐

  1. mysql改动用户password

    登录root用户 用root用户登录控制台. use mysql use mysql,mysql是mysql数据库自己主动创建的一个数据库. 改动user表的数据 update user set pa ...

  2. Docker推出了Docker云,给大家介绍下哈!

    Docker推出了Docker云,给大家介绍下哈. 收到了Docker官网的邮件邀请,他们推出了Docker云:https://cloud.docker.com 账号信息栏目下有: 云提供商:眼下支持 ...

  3. Milk(杭电1070)

    Milk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  4. pandas深入理解

    Pandas是一个Python库,旨在通过“标记”和“关系”数据以完成数据整理工作,库中有两个主要的数据结构Series和DataFrame In [1]: import numpy as np In ...

  5. kettle 使用excel模板导出数据

    通过excel进行高速开发报表: 建设思路: 1.首先制订相关的execl模板. 2.通过etl工具(kettle)能够高速的 将数据库中的数据按excel模板导出成新的excel就可以. 当中ket ...

  6. Linux 安装Redis 5.0

    结构如下: Redis 官方不建议Redis安装在WINDOWS 服务器上(尤其是生产中分布式事物缓存). linux 下Redis 5.0主从复制(一主二从)哨兵模式的搭建:https://www. ...

  7. 如何用写js弹出层 ----2017-03-29

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. 调试相关blogs收集

    Debug Diag官方blog  https://blogs.msdn.microsoft.com/debugdiag/ Tess  https://blogs.msdn.microsoft.com ...

  9. 利用IOC—— Castle进行对象映射,以及结合Nhibernate访问数据库

    相信很多人对IOC这个概念并不陌生,简而言之其核心就是利用反射来创建对象来实现解耦. 具体这么做解耦的好处是什么,因为鄙人做的项目还不多,所以还没体会到. 但好的项目大概是这样的 就是实现“高内聚,低 ...

  10. PHP魔术方法__clone()篇

    PHP中定义了一个内置方法__clone()来调整兑现的克隆行为: 当一个对象被克隆的时候会自动执行__clone()方法,而复制的对象可以在其方法内进行调整 header('Content-type ...