为什么 AccessibilityService 的 onAccessibilityEvent(..) 方法多次读取同一个视图?

Why onAccessibilityEvent(..) method of AccessibilityService is reading the same view many times?

我正在使用 AccessibilityService 来确定 android 设备中任何当前应用程序 运行ning 的文本和视图坐标。 在每个事件 onAccessibilityEvent(...) 运行s 但我不知道如何控制这些事件。我已经使用 event.getSource() 来获取每个 window 内容更改的结果。我的 AccessibilityService 的 xml 设置是:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowContentChanged|typeViewFocused"
    android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
    android:canRetrieveWindowContent="true"
    android:canRequestTouchExplorationMode="true"
    android:packageNames="com.whatsapp"
    android:accessibilityFeedbackType="feedbackSpoken"

/>

并且 onAccessibilityEvent(...) 是:

@Override
    public void onAccessibilityEvent(AccessibilityEvent event) {


        Log.e("MyService: ","Get Source output: "+event.getSource());
        String get_cord= String.valueOf(event.getSource());

         Log.e("MyService: ","Window id is: "+window_ID);


    }

我得到的输出是(我用粗体突出显示了文本值:

08-18 19:34:29.055 20131-20131/com.example.root.without_root E/MyService:: Get Source output: android.view.accessibility.AccessibilityNodeInfo@801b6813; boundsInParent: Rect(0, 0 - 548, 46); boundsInScreen: Rect(144, 1095 - 692, 1141); packageName: com.device; className: android.widget.TextView; **text: Samsung**; error: null; maxTextLength: -1; contentDescription: null; viewIdResName: com.whatsapp:id/name; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: false; longClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null]

08-18 19:34:29.058 20131-20131/com.example.root.without_root E/MyService:: Get Source output: android.view.accessibility.AccessibilityNodeInfo@801b6813; boundsInParent: Rect(0, 0 - 548, 46); boundsInScreen: Rect(144, 1095 - 692, 1141); packageName: com.device; className: android.widget.TextView; **text: Samsung**; error: null; maxTextLength: -1; contentDescription: null; viewIdResName: com.whatsapp:id/name; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: false; longClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null]

08-18 19:34:29.061 20131-20131/com.example.root.without_root E/MyService:: Get Source output: android.view.accessibility.AccessibilityNodeInfo@801b6813; boundsInParent: Rect(0, 0 - 548, 46); boundsInScreen: Rect(144, 1095 - 692, 1141); packageName: com.whatsapp; className: android.widget.TextView; **text: Samsung**; error: null; maxTextLength: -1; contentDescription: null; viewIdResName: com.device:id/name; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: false; longClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null]
08-18 19:34:29.064 20131-20131/com.example.root.without_root E/MyService:: Get Source output: android.view.accessibility.AccessibilityNodeInfo@801b6bd4; boundsInParent: Rect(0, 0 - 548, 38); boundsInScreen: Rect(144, 1141 - 692, 1179); packageName: com.whatsapp; className: android.widget.TextView; text: ☺; error: null; maxTextLength: -1; contentDescription: null; viewIdResName: com.whatsapp:id/status; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: false; longClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null, AccessibilityAction: ACTION_NEXT_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY - null, AccessibilityAction: ACTION_SET_SELECTION - null]

现在您可以看到它 运行 3 次,仅 1 次查看,但我希望它 运行 仅一次,一次查看。请帮我看看我怎样才能做到这一点?

我已经尝试将 xml 中的 accessibilityEventTypes 的值从 "typeAllMasks" 更改为 "typeWindowContentChanged" 和 "typeViewFocused",但没有任何帮助。

我还尝试在 AccessibilityService 的 onAccessibilityEvent(...) 中设置标志,但这也没有用,因为该服务每次都保持 运行ning(如果有人可以做到,那就太好了工作)。

请告诉我如何让它工作!

辅助功能事件经常发生。所以,首先,我希望你考虑一下你是否真的想忽略这些事件。您希望解决什么用户体验问题?

特别是 windowContentChanged 事件和 viewFocused 事件将经常发生的问题。您可以考虑做的一件事是限制事件。对您的服务配置的以下更改 xml 将限制每个特定事件类型每半秒发生一次。

The event notification timeout is useful to avoid propagating events to the client too frequently since this is accomplished via an expensive interprocess call. One can think of the timeout as a criteria to determine when event generation has settled down.

因此,您的服务配置 xml 将如下所示:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowContentChanged|typeViewFocused"
android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
android:canRetrieveWindowContent="true"
android:canRequestTouchExplorationMode="true"
android:packageNames="com.whatsapp"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="500"
/>

但是,值得注意的是,您可能会错过活动。因此,如果您依赖于与这些事件保持同步,您会希望将其设置得更低。这是一种平衡行为。