2

I have written an Android app using AccessibilityService. This means: when a text appears "xxx", it auto clicks it and auto closes. But when I scroll my window or something changed in the window it clicks and closes again.

So I printed accessibilityNodeInfo.toString() in Logcat, but the same accessibilityNodeInfo returns different strings. I'll show the code to clarify what I mean:

AccessibilityNodeInfo previousAccessibilityNodeInfo = null;

mAccessibilityNodeInfo = event.getSource();

if (mAccessibilityNodeInfo == null) {
        return;
    }

if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
    List<AccessibilityNodeInfo> accessibilityNodeInfos
            = mAccessibilityNodeInfo.findAccessibilityNodeInfosByText("xxx");
        if (accessibilityNodeInfos != null && accessibilityNodeInfos.size() > 0) {
            AccessibilityNodeInfo info = accessibilityNodeInfos.get(accessibilityNodeInfos.size() - 1);
            Log.d(TAG,info.toString());
            if (previousAccessibilityNodeInfo == null) {
                previousAccessibilityNodeInfo = info;
                info.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
            else if (previousAccessibilityNodeInfo != null && previousAccessibilityNodeInfo != info) {
                info.getParent().performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
            else {
                return;
            }

        }

    }

// Log info: The same AccessibilityNodeInfo when I scrolled returns different strings.

accessibility.AccessibilityNodeInfo@36eea0;
accessibility.AccessibilityNodeInfo@38443e;
accessibility.AccessibilityNodeInfo@3999dc;
accessibility.AccessibilityNodeInfo@3aef7a;
accessibility.AccessibilityNodeInfo@3c4518;

// In the above code is the same AccessibilityNodeinfo

So how should I compare AccessibilityNodeInfo? Achieve such results that as soon as return if it is a previous marked AccessibilityNodeInfo.

Sorry for my bad English.

Bandreid
  • 2,727
  • 28
  • 47
taken2016
  • 165
  • 1
  • 9
  • Could you please try to clarify the last paragraph? I edited the question but could not understand what you mean by "Achieve such results that as soon as return if it is a previous marked AccessibilityNodeInfo." – Bandreid Jan 19 '16 at 17:27
  • 1
    Thank you very much. I mean: If it is previous accessibilityNodeInfo would not automatically click and automatically close. – taken2016 Jan 20 '16 at 02:03

2 Answers2

0

Every AccessibilityNodeInfo that your service obtains will be a unique object (actually, they are pooled so you may see the same node again after a recycle() call, but within the scope of this question they are unique).

On API 14+, you can use equals() to check that two nodes represent the same view in the same window.

Prior to API 14, AccessibilityNodeInfo does not override equals() or hashCode(), so you won't be able to make an equality comparison between nodes representing the same view. If the view has a unique ID (e.g. View.getId()) set, your best option would be to compare the results of AccessibilityNodeInfo.getViewIdResourceName().

Outside of that, there is no reliable way to compare two AccessibilityNodeInfo objects on API < 14. You could consider using heuristics like location on screen and other available properties, but these are not guaranteed to be unique.

alanv
  • 23,966
  • 4
  • 93
  • 80
  • Thank you for your answer. I have tried it but it always return null :( – taken2016 Jan 20 '16 at 02:21
  • To take advantage of this ensure you add FLAG_REPORT_VIEW_IDS to your AccessiblityServiceInfo flags. Note: This will only return IDs for views that have an ID set either in code, or in XML. For your apps, you can subclass View to ensure each view has an id. For third party apps, good luck. Note: View IDs are not necessarily unique. The ID of say a particular element of a listView cell will likely show up in each cell. You would need to access parent node information, position within parent, to identify a specific unique element – MobA11y Jan 20 '16 at 22:15
  • Updated to reflect API 14+. Please remember that you can suggest edits for out-of-date responses rather than just down-voting them. – alanv Sep 09 '16 at 18:15
0

AccessibilityNodeInfo has both equals() and hashCode() since API 14 (Ice Cream Sandwich). If you look at the source code, you can see that they use the window and view IDs, so two accessibility nodes will be equal if they represent the same view in the same window.

If the views or layout are changing in between calls to onAccessibilityEvent(), then those functions may not work for you. But if the layout and content is staying the same, then you can use them to compare accessibility nodes.

Steve Blackwell
  • 5,904
  • 32
  • 49
  • can you answer this question related to using the accessibility service to perform click action on the notification https://stackoverflow.com/questions/49734263/click-on-the-notification-using-accessibility-service-programmatically – Siva Apr 09 '18 at 16:33