How to change Android talkback instructions for double tap and long press

36.6k Views Asked by At

I have a view that has a long press action handler. I use the content description to set the message Talkback speaks when the view gets focus.

Currently it says my content description right after getting a focus, and after a short pause says:

Double tap to activate, double tap and hold for long press

I want to change this message into something like

Double tap to "action 1", double tap and hold for "action 2"

Is there a way to do so?

I looked into onPopulateAccessibilityEvent(), it gets TYPE_VIEW_ACCESSIBILITY_FOCUSED event, but I wasn't able to change the desired message.

Am I missing something simple?

5

There are 5 best solutions below

4
Justin Morris On BEST ANSWER

It seems AccessibilityAction has changed slightly since alanv posted his answer. Here is a working solution using ViewCompat:

ViewCompat.setAccessibilityDelegate(view, new AccessibilityDelegateCompat() {
    @Override
    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
        // A custom action description. For example, you could use "pause"
        // to have TalkBack speak "double-tap to pause."
        CharSequence description = host.getResources().getText(R.string.my_click_desc);
        AccessibilityActionCompat customClick = new AccessibilityActionCompat(
                    AccessibilityNodeInfoCompat.ACTION_CLICK, description);
        info.addAction(customClick);
    }
});
10
alanv On

In API 21+, you can customize the action names by setting up custom actions on your View's AccessibilityNodeInfo. There are two approaches to this: 1) set an AccessibilityDelegate and override the onInitializeAccessibilityNodeInfo delegate method or 2) extend the view's class and override onInitializeAccessibilityNodeInfo.

Either way, you will be constructing a new AccessibilityAction and setting it on the node using AccessibilityNodeInfo.addAction.

If you chose to use a delegate, you would set a custom description for the click action as follows:

view.setAccessibilityDelegate(new AccessibilityDelegate() {
  @Override
  public void onInitializeAccessibilityNodeInfo(
      View v, AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(v, info);

    // A custom action description. For example, you could use "pause"
    // to have TalkBack speak "double-tap to pause."
    CharSequence description = getResources().getText(R.string.my_click_desc);
    AccessibilityAction customClick = new AccessibilityAction(
            AccessibilityAction.ACTION_CLICK, description);
    info.addAction(customClick);
  }
});

If you application targets API < 21, substitute the appropriate *Compat support library methods. The feature is not backported, so you won't get custom descriptions on API < 21, but you will be able to avoid explicit version checks in your application code.

2
Rubin Yoo On

Use the code below for those who want to remove the all phrase ie. "double tap to".

ViewCompat.setAccessibilityDelegate(view, new AccessibilityDelegateCompat() {
        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            info.addAction(AccessibilityNodeInfoCompat.ACTION_FOCUS);
        }
});

This is basically calling the below code and requestFocus does not have any default talkback announcement associated with it.

case AccessibilityNodeInfo.ACTION_FOCUS: {
                if (!hasFocus()) {
                    // Get out of touch mode since accessibility
                    // wants to move focus around.
                    getViewRootImpl().ensureTouchMode(false);
                    return requestFocus();
                }
            }
4
Azeela On

Use the code below for those who want to remove the all phrase ie. "double tap to activate", "double tap and hold for long press".

mSubTitleText = (TextView) view.findViewById(R.id.txt_subtitle);

 ViewCompat.setAccessibilityDelegate(mSubTitleText, new AccessibilityDelegateCompat() {
            @Override
            public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
                host.setClickable(false);
                host.setLongClickable(false);
            }
        });
0
Thiago On

Here is one sample:

ViewCompat.setAccessibilityDelegate(set_actions_button, object : AccessibilityDelegateCompat() {
    override fun onInitializeAccessibilityNodeInfo(v: View, info: AccessibilityNodeInfoCompat) {
        super.onInitializeAccessibilityNodeInfo(v, info)
        info.addAction(AccessibilityActionCompat(
            AccessibilityNodeInfoCompat.ACTION_CLICK, "Edit note"))
        info.addAction(AccessibilityActionCompat(
            AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, "Copy note"))
    }
})

Take a look at this article which explains very well.