Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AccessibilityEvent.getPackageName() returns null

I am registering an AccessibilityService to listen for app changes. It works on all the phones I've tested but on the Galaxy A3 with Android 5.0 is failing because AccessibilityEvent.getPackageName() is returning null. The packageName should be set, as it is a regular app, downloaded from Google play, being interacted with.

Does anyone know why is this and how to fix it?

Below the relevant parts of my code.

<service
    android:name=".presentation.view.services.LockService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config"/>

    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService"/>
    </intent-filter>
 </service>
@Override
public void onServiceConnected() {
  AccessibilityServiceInfo info = new AccessibilityServiceInfo();

  info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
  info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
  info.notificationTimeout = 100;

  this.setServiceInfo(info);
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
  event.getPackageName() // returns NULL;
}
like image 205
Antonio Nicolás Pina Avatar asked Mar 23 '16 11:03

Antonio Nicolás Pina


1 Answers

As the documentation doesn't specifically explain this, I'll try to provide something that I've came up with after playing around with the AccessibilityService. I'm writing this just in case others are banging their heads because event.getPackageName() always returns null, but don't take my word for granted.

From the documentation of accessibility service, I see that you can set the attribute android:packageNames="@strings/blah_blah", where blah_blah is a comma separated list of package names that our service will observe.

In case we specify this attribute, we will get notified only for those specific packages and event.getPackageName() will return the proper package name.

If we leave this attribute unset or we specifically set this to null we will be notified of all events that occur, but we'll lose the ability to identify whichever specific package "generated" the accessibility event.

As this AccessibilityServiceInfo property can be dynamically set, you could in theory fetch a list of currently installed packages and set that as the packageNames that your service will monitor.

@Override
protected void onServiceConnected() {
    super.onServiceConnected();
    AccessibilityServiceInfo info = getServiceInfo();
    // your other assignments
    info.packageNames = new String[]{...};
    setServiceInfo(info);
}
like image 186
Alex Ionescu Avatar answered Sep 17 '22 17:09

Alex Ionescu