How to “interrupt” an action from execution in an AccessibilityService?

What I am trying to do / What I have done: I am trying to create a basic version of TalkBack for visually impaired users. I made a simple accessibility service that reads content. The button pressed by the user is described and reads it out loud.

@Override public void onAccessibilityEvent(AccessibilityEvent event) { // get the source node of the event AccessibilityNodeInfo source = event.getSource(); if (source == null) { return; } // Check if a button is clicked and speak out the content if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED && BUTTON_CLASS_NAME.equals(source.getClassName()) { Log.d("Button clicked", source.getViewIdResourceName().toString()); convertTextToSpeech(source.getContentDescription().toString()); } if (source != null) source.recycle(); return; } 

Problem: But, in this way, the user cannot listen to the description of the button before performing an action that fires when the button is pressed. By the time the user listens to the description, the button is already pressed, and the action has been completed.

Question: How to interrupt an action (for example: opening a new action after pressing a button) so that it performs so that the user can safely explore the current views on the feedback screen, can I ensure that no new actions or other actions start?

Similar to what is happening in Talkback: custom taps for listening to descriptions and double taps for performing an action. How does Talkback prevent action if the user does not use double taps? I looked at TouchExplorationMode , but I assume that it is mainly used for gestures, not for clicks.

+5
source share
1 answer

You are looking for the wrong place. When onAccessibilityEvent receives the event, the action is already completed. It simply informs you that a click event has occurred. It is already too late to stop him.

You really need TouchExplorationMode. TalkBack processing is implemented quickly and dirty here, and how it makes the user interface behave the way it does without a lot of unwanted message processing and exceptions. I used only part of this thing for this function. There, of course, there are many other necessary forests, but this would distract from the key elements.

The contents of serviceConfig.xml:

 <?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFlags="flagRequestTouchExplorationMode" android:canRequestTouchExplorationMode="true" /> 

Partial Content A11yService.java

 @Override public void onAccessibilityEvent(AccessibilityEvent e) { switch (e.getEventType()) { case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: { e.getSource().performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); } } } 

TalkBack then intercepts gestures in onGesture, and to scroll right or swipe left, grabs them and performs the same action (accessibility focus) only on the next or previous element, bypassing AccessibilityNode. Easy peasy!

+1
source

Source: https://habr.com/ru/post/1245256/


All Articles