5

I have followed this suggestion to unistall my app programatically and everything works fine until Android 7.1, but after when I tested the same on Android 8.1 and 9, this seems to not work (none click is performed on Ui window). What's happening? some update was made about this in these versions?

main code >

MyAccessibility:

public void onAccessibilityEvent(AccessibilityEvent event) {

 AccessibilityNodeInfo source = event.getSource();

    if (source == null) {
        return;
    }

    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {

        List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByViewId("android:id/button1");
        for (AccessibilityNodeInfo node : list) {
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
   }

}

XML (main):

<service
            android:name=".MyAccessibility"
            class=".MyAccessibility"
            android:enabled="true"
            android:exported="false"
            android:label="@string/accessibility_service_label"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action
                    android:name=".MyAccessibility"
                    android:value=".MyAccessibility" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>

            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>

XML (AccessibilityService):

<?xml version="1.0" encoding="utf-8"?>

<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagReportViewIds"
    android:canPerformGestures="true"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_description"
    android:notificationTimeout="100"
    tools:ignore="UnusedAttribute" />

Edit:

Test enviroment:

  • Motorola G5(S) Plus - Android 7.1 and 8.1 (Updated)
  • Motorola G7 Plus - Android 9.0
BrowJr
  • 1
  • 6
  • 22
  • 1
    Make sure you have added appropriate permission for it. `` for more refer this – rex50 Dec 30 '19 at 07:46
  • +1 by importance of this permission on Android Pie. But to goal of this question (`AccessibilityService` click) still not worked. – BrowJr Dec 30 '19 at 12:48
  • make sure that `adb shell pm list packages|grep -i install` gives you `com.android.packageinstaller` otherwise you have to use `com.google.android.packageinstaller` in the `onServiceConnected` method – Lino Dec 31 '19 at 21:38
  • does this help? – Lino Dec 31 '19 at 22:10
  • @Lino, not helped :-( and also not have other physical devices here to test, only these two Motorola. – BrowJr Dec 31 '19 at 22:11
  • that's strange because with emulators seem working... – Lino Dec 31 '19 at 22:14
  • @Lino, Then this can be a bug on android version of Motorola (physical) devices – BrowJr Dec 31 '19 at 22:16
  • 1
    Hey @BrowJr, please stop repeatedly editing your question to delete/add one character which brings your question to the top of the latest questions. Instead, it would be a good idea to use the bounty system which would attract more people. – Edric Jan 01 '20 at 13:53

1 Answers1

3

I did some tests and figured out when trying to uninstall an application on Android 8 and later, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED event fires but AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED event doesn't fire. In addition, when you call AccessibilityEvent.getSource() method on an event of AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED type, it returns null. So I used getRootInActiveWindow() method when AccessibilityEvent.getSource() method returns null and in addition on API 26 and above, I tried to handle AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED event as well.

Please try this code:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {

    AccessibilityNodeInfo source = event.getSource();

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && source == null)
        source = getRootInActiveWindow();

    if (source == null) {
        return;
    }

    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        List<AccessibilityNodeInfo> list = source.findAccessibilityNodeInfosByViewId("android:id/button1");
        for (AccessibilityNodeInfo node : list) {
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
    }
}

I modified accessibility_service_config.xml file as well for more accuracy.

<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagReportViewIds"
    android:canPerformGestures="true"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_description"
    android:notificationTimeout="100"
    tools:ignore="UnusedAttribute"
    android:packageNames="com.google.android.packageinstaller, com.android.packageinstaller"/>

I have tested this code on API 24, API 27, API 28 and API 29 and it worked.

Mir Milad Hosseiny
  • 2,619
  • 14
  • 19