android无障碍

抢红包软件的核心原理----AccessibilityService

使用

1 先新建一个工程,然后在 res 下新建一个 xml 目录,在xml目录内新建一个accessibility_service_config.xml文件,内容如下:

  • packageNames :指定我们要监听哪个应用程序下的窗口活动
  • accessibility_desc:指定在无障碍服务当中显示给用户看的说明信息
  • accessibilityEventTypes:指定我们在监听窗口中可以模拟哪些事件,这里typeAllMask表示所有的事件都能模拟
  • accessibilityFlags:可以指定无障碍服务的一些附加参数,这里我们传默认值flagDefault就行
  • accessibilityFeedbackType:指定无障碍服务的反馈方式,实际上辅助功能(无障碍服务)这个功能是 Android 提供给一些残疾人士使用的,比如说盲人不方便使用手机,就可以借助无障碍服务配合语音反馈来操作手机,而我们其实是不需要反馈的,因此随便传一个值就可以,这里传入feedbackGeneric
  • canRetrieveWindowContent:指定是否允许我们的程序读取窗口中的节点和内容,必须写true
2 创建一个service继承 AccessibilityService。
public class SmartInstallAPKAccessibilityService extends AccessibilityService {

    private static final String TAG = "[SmartInstallAPKAccessibilityService]";
    private Map handleMap = new HashMap<>();

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        AccessibilityNodeInfo nodeInfo = event.getSource();
        if (nodeInfo != null) {
            int eventType = event.getEventType();
            if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
                    eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                if (handleMap.get(event.getWindowId()) == null) {
                    boolean handled = iterateNodesAndHandle(nodeInfo);
                    if (handled) {
                        handleMap.put(event.getWindowId(), true);
                    }
                }
            }

        }
    }

    @Override
    public void onInterrupt() {

    }

    //遍历节点,模拟点击安装按钮
    private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            if ("android.widget.Button".equals(nodeInfo.getClassName())) {
                String nodeCotent = nodeInfo.getText().toString();
                Log.d(TAG, "content is: " + nodeCotent);
                if ("安装".equals(nodeCotent)
//                        || "完成".equals(nodeCotent)
                        || "确定".equals(nodeCotent)
                        || "打开".equals(nodeCotent)) {
                    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    return true;
                }
            }
            //遇到ScrollView的时候模拟滑动一下
            else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (iterateNodesAndHandle(childNodeInfo)) {
                    return true;
                }
            }
        }
        return false;
    }
}

每当有窗口活动时,就会触发 onAccessibilityEvent() 方法,我们根据传入的 AccessibilityEvent 参数来判断当前事件的类型我们只需要监听TYPE_WINDOW_CONTENT_CHANGED和TYPE_WINDOW_STATE_CHANGED这两种事件就可以了,因为在整个安装过程中,这两个事件必定有一个会被触发。当然也有两个同时都被触发的可能,那么为了防止二次处理的情况,这里我们使用了一个Map集合来过滤掉重复事件。然后通过iterateNodesAndHandle方法来进行当前界面节点的判断,如果是按钮节点,我们就判断按钮上的文字是不是安装、完成、确定、打开这几项,如果是,就进行模拟点击。(完成和打开不能同时在代码中进行判断,如果你安装完软件不想打开软件,就保留完成。反之则保留打开) 。

3 注册服务

    
        
    
    

你可能感兴趣的:(android无障碍)