Реализация доступности в пользовательском представлении не дает устной обратной связи

Я включил специальные возможности, и мое устройство говорит, когда я перемещаюсь.

У меня есть пользовательский seekbar, и я реализовал следующее:

onTouchEvent отрывок:

...
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 метод:

    @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;
            }
    }

Я вижу, что onPopulateAccessibilityEvent успешно вызывается в LogCat, но устройство не дает никакого ответа. Я ожидаю, что текущий счет будет прочитан, но ничего.

У кого-нибудь есть понимание?


person HGPB    schedule 25.07.2013    source источник
comment
На какую версию Android вы ориентируетесь? Существуют разные способы сделать это для Gingerbread по сравнению с ICS или JellyBean.   -  person alanv    schedule 25.08.2013


Ответы (1)


Если вы расширяете ProgressBar, вы можете установить текст для исходящих TYPE_VIEW_SELECTED событий. Они отправляются автоматически, когда пользователь настраивает панель поиска.

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

Однако, похоже, вы расширили View. В этом случае вам нужно будет использовать небольшой обходной путь и инициировать объявление, отправив событие VIEW_FOCUSED в ICS, или использовать API announceForAccessibility в JellyBean и более поздних версиях. Для этого потребуется библиотека support-v4 и будет выглядеть так:

/** 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);
}
person alanv    schedule 29.08.2013
comment
Спасибо, вы легенда! - person HGPB; 29.08.2013
comment
Вау, это здорово! Очень сложно найти хорошую документацию по доступности. - person Ross Hambrick; 02.10.2014
comment
Герой. Смешно, однако, что доступность работает при использовании Toast, но не с Snackbar. - person tim; 20.08.2016
comment
На сегодняшний день я не думаю, что AccessibilityRecordCompat больше нужен. - person David; 16.09.2019