Reputation: 81
my code detects the current running application from AccessibilityService but when user expands the status bar no event is called. I tried to add also TYPE_NOTIFICATION_STATE_CHANGED and TYPES_ALL_MASK but nothing has changed. Can anyone help me ?
public void onServiceConnected() {
AccessibilityServiceInfo asi = new AccessibilityServiceInfo();
asi.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
asi.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
if (Build.VERSION.SDK_INT >= 16) {
asi.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
}
setServiceInfo(asi);
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getPackageName() != null) {
//my code
}
}
Upvotes: 1
Views: 1634
Reputation: 18900
Two things. First off, when you set the accessibility service info I recommend doing so like this:
AccessibilityServiceInfo info = getServiceInfo();
//Set things in here
setServiceInfo(info);
Now, this won't fix this issue. But, it's a good practice. You don't want to nuke all of the settings from your service config XML. Plus, there are some initialization options and stuff that are difficult to get correct without letting the Android system initialize the info object for you. Just grab the current one, tweak it to your liking, and reset. In fact, I see no changes you've made that can be edited in the service_config xml file. Use the service XML configuration, it's a better overall practice!
Now, the issue you're having is your configuration is ALL wrong. Note eventTypes
is a bit mask. That means that in the following line:
asi.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
You are saying ONLY listen for WINDOW_STATE_CHANGED
events. This is silly. What I like to do is set to TYPE_ALL_MASK, until I know exactly which notifications are triggered for the events that I want. Then filter those out later. You can also use TYPE_ALL_MASK and filter using a switch statement, and this is ultimately necessary if you're listening to widely differing events, because different events populate different information (EX: Not all events have a source node info).
Now, why the types of events you're using are not working:
TYPE_NOTIFICATION_STATE_CHANGED: This event fires when a new notification is added, NOT when you scroll down the notification window.
TYPE_WINDOW_STATE_CHANGED: This fires when a view that takes up the entire screen and expects interaction before allowing access to the background content pops up. Things like modal dialogues, menus, etc. The definition of this is really sketchy, and not consistent. I believe in the backend the thing that ultimately triggers this is the drawing of any view that requires the "SYSTEM_ALERT_VIEW" permission, and NOT the definition I gave. But, that definition is the intent... YEAH Android accessibility documentation kind of sucks.
So, now we know the problem. I recommend A: not using code to configure your service info and B: watch ALL events with TYPE_ALL_MASK, and figure out which events fire most consistently. If you watch all events, you will likely see many accessibility events fire when the notification bar is scrolled down. pick the one that is most reliable/happens at the oppurtune moment for you (EX: some might fire before all content is rendered...), and THEN filter for that.
Here's where I'd start.
AndroidManifest.xml service configuration:
<service
android:name=".A11yService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/service_config" />
</service>
service_config xml file:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
android:canRetrieveWindowContent="true"
android:canRequestTouchExplorationMode="true"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:settingsActivity="com.deque.accessibilityanalyzer.SettingsActivity"
/>
Upvotes: 3