学习最好的方法就是: 查看官方,官方,官方的文档; 虽然不够详细,但足够权威;

无障碍官方指南: https://developer.android.com/guide/topics/ui/accessibility/index.html

推荐博文: http://www.tuicool.com/articles/FRFnq2


1:AndroidManifest.xml添加声明

<manifest> 
  <application> 
    <service  android:name = ".RsenAccessibilityService" 
        <!--用于显示在设置界面的标签.就跟桌面图标下面的标签一样的作用-->
        android:label = "@string/accessibility_service_label" 
        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/accessibility_service_config"  /> <!--注意此处-->
    </service> 
    <uses-permission  android:name = "android.permission.BIND_ACCESSIBILITY_SERVICE"  /> 
  </application> 
</manifest>

注意:RsenAccessibilityService必须继承 AccessibilityService
并且实现:

public void onAccessibilityEvent(AccessibilityEvent event) {}
public void onInterrupt() {}

这2个方法.

1.1: accessibility_service_config.xml 内容

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    //用于描述此服务的信息,会显示在系统开启服务的设置界面
    android:description="@string/app_accessibility_description"
    //接收EventTypes的包名,多个包名用,隔开
    android:packageNames="com.tencent.mm,com.tencent.mobileqq"
    //可以接收的事件
    android:accessibilityEventTypes="typeAllMask"
    //字面意思:反馈类型.官方解释真的"很详细".
    android:accessibilityFeedbackType="feedbackAllMask"
    //发送2次事件的时间间隔,超过后事件作废
    android:notificationTimeout="100"
    //设置界面,在系统的启动服务界面会出现一个设置按钮,用来打开这个Activity的;
    android:settingsActivity="com.angcyo.SettingsActivity"
    //官方解释很模糊,暂且就使用缺省值吧
    android:accessibilityFlags="flagDefault"
    //表明此服务是否可以读取窗口中的内容,应该是最重要的属性了.在运行时不可修改;
    android:canRetrieveWindowContent="true"/>

具体的属性解释: https://developer.android.com/guide/topics/ui/accessibility/services.html

2:AccessibilityService服务的编写

public class RsenAccessibilityService extends AccessibilityService {

  @Override
  protected void onServiceConnected() {
      super.onServiceConnected();
      // setServiceInfo();//这个方法同样可以实现xml中的配置信息
  }

  @Override
  public boolean onUnbind(Intent intent) {
      //关闭服务时,调用
      return super.onUnbind(intent);
  }

  @Override
  public void onAccessibilityEvent(AccessibilityEvent event) {
      //当窗口发生的事件是我们配置监听的事件时,会回调此方法.会被调用多次
  }

  @Override
  public void onInterrupt() {
      //当服务要被中断时调用.会被调用多次
  }
}

到达这一步,程序已经可以正常运行了;
只要com.tencent.mm,com.tencent.mobileqq
这2个包的程序有我们监听的事件(android:accessibilityEventTypes=”typeAllMask”)那么,
onAccessibilityEvent方法就会回调.这样的话就可以进行下一步操作了;(注意:需要在系统中开启此服务)


常用事件:

TYPE_WINDOW_STATE_CHANGED   :32
TYPE_VIEW_SELECTED          :4
TYPE_VIEW_FOCUSED           :8
TYPE_WINDOW_CONTENT_CHANGED :2048
TYPE_VIEW_CLICKED           :1
TYPE_VIEW_SCROLLED          :4096

TYPE_VIEW_TEXT_SELECTION_CHANGED :8192
TYPE_VIEW_TEXT_CHANGED           :16

所有事件及详情: https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html

3:常用的方法

AccessibilityService.performGlobalAction(GLOBAL_ACTION_BACK);//类似于点击导航上的返回按钮
//检查服务是否开启
private boolean isServiceEnabled() {
  AccessibilityManager accessibilityManager =    (AccessibilityManager)getSystemService(Context.ACCESSIBILITY_SERVICE);

  List<AccessibilityServiceInfo> accessibilityServices =
        accessibilityManager.getEnabledAccessibilityServiceList(
        AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
  for (AccessibilityServiceInfo info : accessibilityServices) {
      if (info.getId().contains("com.angcyo.accessibility.RsenAccessibilityService")) {
          return true;
      }
  }
  return false;
}
//打开系统无障碍设置界面
Intent accessibleIntent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(accessibleIntent);
//根据文本,返回文本对应的View
AccessibilityNodeInfo source = event.getSource();
AccessibilityNodeInfo listNode = source.getChild(0).getChild(1);
List<AccessibilityNodeInfo> itemList = listNode.findAccessibilityNodeInfosByText("文本");
//通常需要配合getParent(),或者getChild(),方法一起使用;
//拿到View之后,就可以调用"单击事件","滚动事件",等所有支持的事件了
//info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
//listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
//检测当前是那个界面,也是通过查找这个界面固有的文本信息,来判断;

至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.