AccessibilityService 忽略 notificationTimeout 属性
AccessibilityService ignores notificationTimeout property
据我了解,设置 AccessibilityService 的 notificationTimeout 属性 应该可以限制 onAccessibilityEvent 的调用频率高于该超时值。我已经尝试在辅助功能服务的 xml 文件中和以编程方式使用 setServiceInfo.
进行设置
但是无论我将其设置为什么,我都会非常频繁地调用 onAccessibilityEvent。
这是我的一些代码:
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;
}
无论我将其设置为什么,notificationTimeout 调试日志都能正确读取,但我收到的调用频率高达 0 毫秒,即使它应该等待整整一秒!
这是一个类似的问题:Notification Timeout - Specifying delay between accessibility events
通过阅读源码可以发现,如果事件类型是WINDOW_CONTNET_CHANGE,那么通知超时是没有用的。看来这是设计使然。也许他们希望尽快WINDOW_CONTENT_CHANGE事件通知。
您可以将 xml 中的事件类型更改为 WINDOW_CONTNET_CHANGE 中的其他类型,然后通知超时将起作用。
如果您必须使用 WINDOW_CONTNET_CHANGE,您可以在 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)
据我了解,设置 AccessibilityService 的 notificationTimeout 属性 应该可以限制 onAccessibilityEvent 的调用频率高于该超时值。我已经尝试在辅助功能服务的 xml 文件中和以编程方式使用 setServiceInfo.
进行设置但是无论我将其设置为什么,我都会非常频繁地调用 onAccessibilityEvent。
这是我的一些代码:
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;
}
无论我将其设置为什么,notificationTimeout 调试日志都能正确读取,但我收到的调用频率高达 0 毫秒,即使它应该等待整整一秒!
这是一个类似的问题:Notification Timeout - Specifying delay between accessibility events
通过阅读源码可以发现,如果事件类型是WINDOW_CONTNET_CHANGE,那么通知超时是没有用的。看来这是设计使然。也许他们希望尽快WINDOW_CONTENT_CHANGE事件通知。
您可以将 xml 中的事件类型更改为 WINDOW_CONTNET_CHANGE 中的其他类型,然后通知超时将起作用。
如果您必须使用 WINDOW_CONTNET_CHANGE,您可以在 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)