Подтвердить что ты не робот

Проблемы с реализацией функции доступности в Android

Я разрабатываю приложение, которое рассматривает книги. Существует экран (Activity), который показывает книгу. Он имеет пользовательский вид, что-то похожее на ViewSwitcher, и каждая страница представляет собой растровое изображение, которое отображается обычным представлением.

Теперь я должен реализовать функцию доступности - книгу следует читать по телефону (аудио).

Я читал раздел "Доступность" здесь https://developer.android.com/guide/topics/ui/accessibility/index.html, но он недостаточно ясен.

Я использую SupportLibrary для управления доступностью, и теперь у меня есть этот код в ViewGroup (который управляет страницами книг). Код 1:

private class EditionPagesViewSwitcherAccessibilityDelegate extends AccessibilityDelegateCompat {

    private int mPageCount;
    private double[] mPageRange;

    @Override
    public void onInitializeAccessibilityEvent(final View host, final AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);
        event.setClassName(EditionPagesViewSwitcher.class.getName());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            event.setScrollable(canScroll());
        }
        if (event.getEventType() == AccessibilityEventCompat.TYPE_VIEW_SCROLLED && updatePageValues()) {
            event.setItemCount(mPageCount);
            // we use +1 because of user friendly numbers (from 1 not 0)
            event.setFromIndex((int) (mPageRange[0] + 1));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                event.setToIndex((int) (mPageRange[1] + 1));
            }
        }
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(final View host, final AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
        info.setClassName(EditionPagesViewSwitcher.class.getName());

        info.setScrollable(canScroll());
        info.setLongClickable(true);
        if (canScrollForward()) {
            info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
        }
        if (canScrollBackward()) {
            info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
        }
    }

    @Override
    public boolean performAccessibilityAction(final View host, final int action, final Bundle args) {
        if (super.performAccessibilityAction(host, action, args)) {
            return true;
        }
        switch (action) {
            case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD: {
                if (canScrollForward()) {
                    showNext();
                    return true;
                }
            }
            return false;
            case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD: {
                if (canScrollBackward()) {
                    showPrevious();
                    return true;
                }
            }
            return false;
        }
        return false;
    }

Вот код из просмотра страницы Код 2:

    @Override
    public void onInitializeAccessibilityEvent(final View host, final AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(host, event);

        event.setClassName(EditionPageView.class.getName());
        if (hasText()) {
            event.getText().add(getPageRangeText());
            final String trimText = mSurfaceUpdateData.getPageText().trim();
            if (trimText.length() > MAX_TEXT_LENGTH) {
                event.getText().add(trimText.substring(0, MAX_TEXT_LENGTH));
//              event.getText().add(trimText.substring(MAX_TEXT_LENGTH, trimText.length()));
            }
            else {
                event.getText().add(trimText);
            }
        }
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(final View host, final AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);

        info.setClassName(EditionPageView.class.getName());
    }

Поскольку текстовые данные страницы загружают асинхронную доступность первого времени, не имеют никакого текста во время выполнения onInitializeAccessibilityEvent кода. А затем, когда данные были загружены, я запускаю события AccessibilityEvent.TYPE_VIEW_SELECTED и AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED. Затем onInitializeAccessibilityEvent выполняет снова и телефон "читает" текст книги.

Итак, мои вопросы:

  • Является ли моя реализация доступности доступной? Может быть, дизайн неправильный? Потому что я не нашел хорошего учебника об этой функции.
  • Почему мне нужно использовать проверки версий SDK в реализациях поддержки в Code 1? Почему поддержка реализации не справляется с этим правильно?
  • Нужно ли стрелять TYPE_VIEW_SELECTED и TYPE_VIEW_TEXT_CHANGED? Или может быть какой-то другой код должен быть реализован?
  • Основной вопрос. В коде 2 есть прокомментированная строка кода. Этот текст подстроки кода будет меньше MAX_TEXT_LENGTH (это 3800), потому что, если текст больше, ничего не воспроизводится. Ничего. Это ограничение доступности? Любой другой текст, который меньше этого значения, хорошо воспроизводится.
  • Кто-нибудь знает, где я могу найти хороший учебник? (да, я видел образцы).
  • Есть ли у кого-нибудь какие-либо пользовательские реализации для просмотра?

ОБНОВЛЕНО

Ну. Вот несколько ответов:

  • Как я вижу, события TYPE_VIEW_SELECTED и TYPE_VIEW_TEXT_CHANGED не нужны, если вы не хотите, чтобы этот текст читался, как только вы его получили.
  • На Nexus 7 весь большой текст воспроизводится хорошо (текст до 8000 символов), поэтому этот вопрос не воспроизводится на нем, а на Samsung Galaxy Tab 10.1 (Android 4.0.4) и эмуляторе Genymotion Tab 10.1 с Android 4.3 делает. И это странно...
4b9b3361

Ответ 1

4.. Согласно документации String.substring() Первый аргумент, который вы передаете, является начальным индексом в исходной строке, второй аргумент - конечным индексом в исходной строке.

Пример:

String text = "Hello";
partOfText = text.substring(2,text.length() - 1);

partOfText равен "llo" (первый char - индекс 0)

Итак, поставив константу MAX_TEXT_LENGTH в качестве первого аргумента, она начнет с индекса 3800 вынуть подстроку.

http://developer.android.com/reference/java/lang/String.html#substring (int)

Ответ 2

Вы правы, MAX_TEXT_LENGTH - 3800.

О ваших сомнениях,

этот код:

 event.getText().add(trimText.substring(MAX_TEXT_LENGTH, trimText.length()));
        }

вы пытаетесь подстроить "trimText" от MAX_TEXT_LENGTH до trimText.length()! Предположим, что trimText = "STACK", trimText.length() = 5, то trimText.substring(3800,5) будет?

Сначала это не имеет смысла, правильно используя это: trimText.substring(0,2) = "ST";