Android AccessibilityService:如何记录和重播视图点击?

时间:2015-04-27 08:57:20

标签: android accessibility

我正在尝试实现一个记录用户操作的AccessibilityService(此时只点击事件)并存储它们,以便以后重播它们。

为此,我注册了AccessibilityEvent.TYPE_VIEW_CLICKED个事件并检查我是否可以通过两个策略以后以某种方式恢复它们(当我所有的都是对活动的窗口/根节点的引用时):

  1. 获取点击后的视图ID并在根节点树中查找此ID
  2. 获取点击后的观看文字并在根节点树中查找此文字
  3. 我已在各种应用程序和Android系统的不同部分对此进行了测试,结果非常混乱。大约一半的观点无法通过两种策略中的任何一种进行恢复,有些观点有时被报告为可恢复的,有时甚至没有。我发现后者是由于竞争条件造成的,因为可访问性服务的运行方式与点击的视图所属的应用程序不同。

    我现在的问题是,是否有更好的方法来获取辅助功能中的视图句柄,并在稍后的应用程序执行中再次查找此视图。

    下面是我的AccessiblityService类的代码:

    public class RecorderService extends AccessibilityService {
    
        private static final String TAG = "RecorderService";
    
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
    
            switch (event.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
                AccessibilityNodeInfo node = event.getSource();
    
                if (node == null) {
                    Log.i(TAG, "node is null");
                    return;
                }
    
                AccessibilityNodeInfo root = getRootInActiveWindow();
                if (root == null) {
                    Log.i(TAG, "root is null");
                    return;
                }
    
                // Strategy #1: locate node via its id
                String id = node.getViewIdResourceName();
                if (id == null) {
                    Log.i(TAG, "id is null");
                } else {
    
                    List<AccessibilityNodeInfo> rootNodes = root.findAccessibilityNodeInfosByViewId(id);
                    if (rootNodes.size() == 1) {
                        Log.i(TAG, "success (via id)");
                        return;
                    } else {
                        Log.i(TAG, "multiple nodes with that id");
                    }
                }
    
                // Strategy #2: locate node via its text
                CharSequence text = node.getText();
                if (text == null) {
                    Log.i(TAG, "text is null");
                } else {
                    List<AccessibilityNodeInfo> rootNodes = root.findAccessibilityNodeInfosByText(text.toString());
                    if (rootNodes.size() == 1) {
                        Log.i(TAG, "success (via text)");
                        return;
                    }
                }
    
                Log.i(TAG, "failed, node was not recoverable");
            }
        }
    
        @Override
        protected boolean onKeyEvent(KeyEvent event) {
            Log.i("Key", event.getKeyCode() + "");
    
            return true;
            // return super.onKeyEvent(event);
        }
    
        @Override
        public void onInterrupt() {
        }
    }
    

    我正在开发SDK版本21(Lollipop)并在HTC Nexus M8和三星Galaxy Note2上进行测试,两者都显示出类似的结果。

0 个答案:

没有答案