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

时间:2017-08-18 14:35:22

标签: android accessibility accessibilityservice android-accessibility

我正在使用AccessibilityService来确定在Android设备中运行的任何当前应用程序的视图的文本和坐标。 onAccessibilityEvent(...)上的每个事件都会运行,但我不知道如何控制这些事件。我使用了event.getSource()来获取每个窗口内容更改的结果。我的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(...)中设置标志,但这也没有用,因为服务每次都在运行(如果有人可以使它工作的话会很棒。)

请告诉我如何才能让它发挥作用!

1 个答案:

答案 0 :(得分:2)

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

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

  

事件通知超时有助于避免过于频繁地将事件传播到客户端,因为这是通过昂贵的进程间调用完成的。可以将超时视为确定事件生成何时稳定下来的标准。

因此,您的服务配置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"
/>

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