As I understand it, setting an AccessibilityService's notificationTimeout property should limit onAccessibilityEvent from being called more frequently than that timeout. I have tried setting this both in the accessibility service's xml file and programmatically with setServiceInfo.
However no matter what I set it to, I get very frequent calls of onAccessibilityEvent.
Here's some of my code:
XML:
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagReportViewIds|flagIncludeNotImportantViews"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"
android:notificationTimeout="100">
JAVA:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
accessibilityServiceInfo.notificationTimeout = 1000;
setServiceInfo(accessibilityServiceInfo);
Utils.logDebug(TAG, "TIMEOUT: " + getServiceInfo().notificationTimeout);
long currentTime = System.currentTimeMillis();
long timeSinceLastEvent = currentTime - timeLastAccessibilityEvent;
Utils.logDebug(TAG, "onAccessibilityEvent(), type: " + event.getEventType() + ", last event: " + timeSinceLastEvent + "ms ago");
if(!event.equals(lastAccessibilityEvent) && timeSinceLastEvent < MAX_FREQUENCY_ACCESSIBILITY_EVENT_MS) {
Utils.logDebug(TAG, "Too soon, returning!");
timeLastAccessibilityEvent = currentTime;
return;
}
timeLastAccessibilityEvent = currentTime;
}
The notificationTimeout debug log reads correctly for whatever I set it to, but I get calls as frequent as 0ms old even though it should be waiting a full second!
Here is a similar question: Notification Timeout - Specifying delay between accessibility events
By reading the source code, you can find that if the event type is WINDOW_CONTNET_CHANGE, the notification timeout is useless. It seems it is by design. Maybe they want WINDOW_CONTENT_CHANGE event notice as soon as possible.
You can change the event type in your xml by other TYPEs inside of WINDOW_CONTNET_CHANGE, then the notification timeout will work.
If you have to use WINDOW_CONTNET_CHANGE, you can set a timer to drop extra incoming events in your onAccessibilityEvent().
if ((mNotificationTimeout > 0)
**&& (eventType != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)**) {
// Allow at most one pending event
final AccessibilityEvent oldEvent = mPendingEvents.get(eventType);
mPendingEvents.put(eventType, newEvent);
if (oldEvent != null) {
mEventDispatchHandler.removeMessages(eventType);
oldEvent.recycle();
}
message = mEventDispatchHandler.obtainMessage(eventType);
} else {
// Send all messages, bypassing mPendingEvents
message = mEventDispatchHandler.obtainMessage(eventType, newEvent);
}
message.arg1 = serviceWantsEvent ? 1 : 0;
mEventDispatchHandler.sendMessageDelayed(message, mNotificationTimeout)