Android: How to make Explore-By-Touch / Talkback repeat the ContentDescription of the current View in AccessibilityFocus?

In my Android app, I have a View that displays an image and has a ContentDescription associated with it.

I can turn on Settings-> Accessibility-> Talkback, using Explore By Touch from the Talkback settings, and then tap View once to read the ContentDescription aloud.

This is all as expected.

However, I would like Explore By Touch to repeat the ContentDescription if I touch the same View again. For example, my image and description can be updated as long as it has an AccessibilityFocus , so the new phrase will be useful to the user. How can I achieve this?

I tried experimenting with View.clearFocus() and View.invalidate() , but without success.

Any constructive ideas would be welcome.

Update

I should also mention that I want to add support for API 8 and beyond. Therefore, I try to do my best with the Accessibility interface from API 4.

I am currently working on a solution that uses View.clearFocus() and then View.requestFocus() to get around the problem with the updated view. This seems to work so far in my test suite with APIs 8 and 16.

I will update the final result again, but will continue to offer additional suggestions.

+6
source share
1 answer

As promised in my question, here are the results of my investigation and a working solution.

Firstly, many thanks to alanv for his help and support, as well as for answering the question about later APIs (14 and above). Although he did not find a solution for the older APIs, he provided important information that helped me find the answer.

At the time of writing, it is not possible to create a successful AccessibilityEvent due to a known error in TalkBack - see Send an accessibility event that is not associated with a view for more details. If the event source is zero, the event is ignored by TalkBack (v3.5.0_r105), and as AccessibilityEvent.setSource(View) first appeared in API 14 , it is not possible to set the source before that - see Google Eyes-Free Problem # 379

However, you can get Android to generate such events using View.requestFocus() , as I previously hinted.

  • Make your view more attractive in the XML layout by using:

    android:focusable="true"
    android:focusableInTouchMode="true"

  • Set the text text using View.setContentDescription(text) in Activity.onCreate or using android:contentDescription="text" in the XML layout if it is static or dynamic in the code, if necessary.

  • When verbal text is required, move the focus to the correct view using View.requestFocus() to call AccessibilityEvent .

  • To repeat the phrase (my original question), call View.clearFocus() before requesting focus in the previous step.

I have a proven implementation of this approach working on API 8 and it also works with API 16. It should work before API 4 when accessibility APIs .

This solution may not be required for developers who only support the latest Android APIs (14 and later), but I believe that there are currently several other options for those who support Accessibility in earlier APIs. Good luck.

Update

Unfortunately, alanv's answer seems to have disappeared, possibly deleted - taking with it all the related details and discussion in the comments. I tried to play the highlights below.

  • For Android API 14 and later, you can create focused events as follows:

    if (mAccessibilityService.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_VIEW_FOCUSED); event.setSource(myView); // API 14 & later event.setClassName(myView.getClass().getName()); event.setPackageName(myView.getContext().getPackageName()); event.setEnabled(true); event.setContentDescription(text); myView.sendAccessibilityEventUnchecked(event); }

  • For Android API 16 and later, you can use View.announceForAccessibility(text) .

+8
source

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


All Articles