How to stop Accessibility from announcing android button as "button"?

11,894

Solution 1

You're trying to do things that are the responsibility of the AT. The AT knows that the object is a button due to its class type. The AT knows that it is clickable, because Clickable is a valid accessibility action.

TalkBack will then share this information, here is the breakdown: "Next button, (pause) double tap to select"

"Next" -> Content Description/Text. This is the part you control.

"Button" -> Calculated in TalkBack based off of the valid actions and type(class) of the object.

"Double tap to select" -> This announcement is based off of Clickable being a valid accessibility action.

SO, when you set the contentdescription to "Next ....." you end up with an announcement of "next ....... button (pause) double tap to select" and no, there is no way to override this.

IF you are absolutely intent on making your app less accessible, you could create a custom control, write your own gesture recognizers (as in not using "onClick" events, because this would make your element accessibility clickable) to recognize tap gestures. And then write your own content description, that includes name, role, and instructions yourself.

This would be very silly in my opinion! Just let the content-description be "next" and let TalkBack tell users that your element is a button and how to interact with it. While perhaps not the "perfect" wording you/whoever this requirement came from's vision. It will be the way TalkBack users are accustomed to having this type of control announced. Consistency is sometimes more important than having things "just so".

Solution 2

I know I'm way late to the game, but posting an answer here for anyone that may happen to come across this post.

The others are right... we should not be putting the type of widget or how to interact with the widget in the content description. However, all is not lost.

Starting with API 21, there is a way to customize the interaction text through AccessibilityNodeInfo. You can use this class in two different ways:

AccessibilityNodeInfo has a getActionList() method. You can add customize the text that is read out by TalkBack by adding a new item to that list:


info.getActionList().add(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityAction.ACTION_CLICK, "select");


The above code should change "Double-tap to activate" to "Double-tap to select". I say should because I'm just writing that code from memory... I haven't verified it's 100% correct, but it should be something along those lines.

There are two ways to utilize that class, and the one you choose is going to depend on your situation.

Method 1: Subclass your view:

If you create a subclass of the view you are using (in the case of the OP it would be a subclass of Button) then you can override the onInitializeAccessibilityNodeInfo() method and put the code there. Documentation: https://developer.android.com/reference/android/view/View.html#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo)

Method 2: Create a view accessibility delegate

This can be a bit more tricky and involved, but it does offer a ton of flexibility because you don't have to subclass the views you are working with.

Every view has a method that allows you to set an accessibility delegate, which acts like a man-in-the-middle and you can tweak things for accessibility purposes before the info goes to TalkBack.

Documentation: https://developer.android.com/reference/android/view/View.html#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)

So basically you create a subclass of View.AccessibilityDelegate and override it's onInitializeAccessibilityNodeInfo() method with the code I posted above.

Documentation: https://developer.android.com/reference/android/view/View.AccessibilityDelegate.html#onInitializeAccessibilityNodeInfo(android.view.View,%20android.view.accessibility.AccessibilityNodeInfo)

Last but not least...

I did come across a way to stop the "Double tap to activate" text from being spoken out by Talkback. This should only be used when it really does make sense to remove it.

I repeat... this is not normally something you want to do.

I did recently come across a case where it made sense. I was using a TabLayout, and I noticed that Talkback would always read out "Double-tap to select" when the focus was on the selected tab (yes, I had used the method described above to change the text). Well... we don't want to tell the user to select a tab that is already selected, especially when the action results in a no-op. So, I used this little trick to get rid of that, but only for the currently selected tab. I left the unselected tabs alone so that Talkback would still give them the interaction text.

In your onInitializeAccessibilityNodeInfo() method, you can put the following code to remove that text:

info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);

Again, I'm writing this code from memory, so I don't know if that's 100% there, but it gives you the gist of what to do.

Share:
11,894
akash89
Author by

akash89

I am an Android Developer.

Updated on July 27, 2022

Comments

  • akash89
    akash89 almost 2 years

    I have a button in Android which has text "Next" written on it. when, I have the accsessibility cursor focus on the button, it reads out "Next button". This is something I don't want. I want whenever, the cursor to have focus on the "Next" button, it must read out as "Next button. Double tap to select". This I can easily do, by setting the btn.contentDescription("Next button. Double tap to select"), but then it reads out as "Next button. Double tap to select button", means it additionally reads out the last button, which seems very odd, with the "button" text getting read twice.

    Is there any way, by which I can stop the last button to be announced?

  • ChrisCM
    ChrisCM almost 7 years
    The "hint" attribute is only for EditText boxes. Also, that's not how the hint attribute behaves in Android. The hint is the text that sits in EditBoxes before the user fills them out. You have, however, described the behavior hints in iOS perfectly!
  • Malba
    Malba about 5 years
    I have a custom component, that is marked as not clickable, but Talkback still reads out "Double Tap To Activate" giving the user the false impression that they can action something on the component which is wrong. So in some cases, especially with custom components, Talkback needs some help to provide the best experience for a user.
  • ChrisCM
    ChrisCM about 5 years
    There are limited scenarios in which TalkBack reads this out. If you remove all those scenarios, TalkBack won't read this out. If you don't, your control isn't set up properly. You should ask another question about why your particular custom component is behaving this way...