Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing accessability on custom view gives no verbal feedback

I have turned accessability on, and my device speaks as I navigate around.

I have a custom seekbar and have implemented the folllowing:

onTouchEvent excerpt:

...
case MotionEvent.ACTION_MOVE:

    getParent().requestDisallowInterceptTouchEvent(true);

    setTouchAngle(pointToAngle(touchX, touchY));
    score = getScoreFromAngle(angleStart,touchAngle);
    if (onScoreSetListener != null) {
        onScoreSetListener.onScorePoll(this, score);
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
    }
    break;
...

onPopulateAccessibilityEvent method:

    @Override
    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
        super.onPopulateAccessibilityEvent(event);

        LogUtils.i(TAG,"onPopulateAccessibilityEvent()",null);

        switch (event.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:

                LogUtils.d(TAG,"dispatchPopulateAccessibilityEvent() TYPE_VIEW_TEXT_CHANGED",null);

                event.getText().add(String.valueOf(getScore()));
                break;
            }
    }

I can see onPopulateAccessibilityEvent being called in LogCat successfully, but the device is not giving any feedback. I expect the current score to be read back, but nothing.

Does anyone have any insight?

like image 510
HGPB Avatar asked Jul 25 '13 15:07

HGPB


People also ask

What is sendAccessibilityEvent?

sendAccessibilityEvent(): This method is used when user is intended to take an “action” onto your custom view. For example, if a user clicks on your custom view, you will be required to override onTouchEvent(MotionEvent event), then apply switch case on event.

How do you create an Accessibility service?

Go to Settings > Accessibility. The Global Action Bar Service is installed on your device. The accessibility service requests permission to observe user actions, retrieve window content, and perform gestures on behalf of the user! When using a third party accessibility service, make sure you really trust the source!

Which of the following Accessibility tools comes built in with most Android devices?

Explore Android accessibility apps & services Download Android Accessibility Suite, which includes the Accessibility Menu, Select to Speak, Switch Access, and TalkBack. You can find Android Accessibility Suite on devices with Android 9 and higher.


1 Answers

If you're extending ProgressBar, you can set the text for outgoing TYPE_VIEW_SELECTED events. These are sent automatically as the user adjusts the seek bar.

@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.getText().add(...);
}

However, it looks like you may have extended View. In this case, you will need to use a slight workaround and trigger an announcement by sending a VIEW_FOCUSED event on ICS, or use the announceForAccessibility API on JellyBean and above. Which would require the support-v4 library and would look like this:

/** The parent context. Used to obtain string resources. */
private final Context mContext;

/**
 * The accessibility manager for this context. This is used to check the
 * accessibility enabled state, as well as to send raw accessibility events.
 */
private final AccessibilityManager mA11yManager;

/**
 * Generates and dispatches an SDK-specific spoken announcement.
 * <p>
 * For backwards compatibility, we're constructing an event from scratch
 * using the appropriate event type. If your application only targets SDK
 * 16+, you can just call View.announceForAccessibility(CharSequence).
 * </p>
 *
 * @param text The text to announce.
 */
private void announceForAccessibilityCompat(CharSequence text) {
    if (!mA11yManager.isEnabled()) {
        return;
    }

    // Prior to SDK 16, announcements could only be made through FOCUSED
    // events. Jelly Bean (SDK 16) added support for speaking text verbatim
    // using the ANNOUNCEMENT event type.
    final int eventType;
    if (Build.VERSION.SDK_INT < 16) {
        eventType = AccessibilityEvent.TYPE_VIEW_FOCUSED;
    } else {
        eventType = AccessibilityEventCompat.TYPE_ANNOUNCEMENT;
    }

    // Construct an accessibility event with the minimum recommended
    // attributes. An event without a class name or package may be dropped.
    final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
    event.getText().add(text);
    event.setEnabled(isEnabled());
    event.setClassName(getClass().getName());
    event.setPackageName(mContext.getPackageName());

    // JellyBean MR1 requires a source view to set the window ID.
    final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
    record.setSource(this);

    // Sends the event directly through the accessibility manager. If your
    // application only targets SDK 14+, you should just call
    // getParent().requestSendAccessibilityEvent(this, event);
    mA11yManager.sendAccessibilityEvent(event);
}
like image 132
alanv Avatar answered Sep 24 '22 03:09

alanv