Android: как заставить Explore-By-Touch/Talkback повторить ContentDescription текущего представления в AccessibilityFocus?

В моем приложении для Android у меня есть View который отображает изображение и имеет связанный ContentDescription,

Я могу включить Настройки-> Специальные возможности->Talkback с помощью функции " Изучение касанием" в настройках Talkback, а затем одним нажатием на кнопку "Вид" прочитать ContentDescription вслух.

Это все, как и ожидалось до сих пор.

Тем не менее, я хотел бы исследовать на ощупь, чтобы повторить ContentDescription если я нажму один и тот же View снова. Например, моё изображение и описание могут быть обновлены, пока AccessibilityFocusТак что новая фраза была бы полезна для пользователя. Как мне этого добиться?

Я пытался экспериментировать с View.clearFocus() а также View.invalidate(), но безуспешно.

Любые конструктивные идеи приветствуются.

Обновить

Я должен был также упомянуть, что я хочу добавить поддержку API 8 и выше. Поэтому я пытаюсь сделать все возможное, используя интерфейс Accessibility из API 4.

В настоящее время я работаю над решением, которое использует View.clearFocus() с последующим View.requestFocus() обойти проблему обновленного просмотра. Похоже, это работает на моем тестовом наборе с API 8 и 16.

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

1 ответ

Решение

Как и было обещано в моем вопросе, вот результаты моего исследования и рабочее решение.

Во-первых, большое спасибо alanv за его помощь и поддержку, а также за ответ на вопрос для последующих API (от 14 и выше). Хотя он не нашел решения для более старых API, он предоставил важную информацию, которая помогла мне найти ответ.

На момент написания, невозможно построить успешно разговорный AccessibilityEvent, из-за известной ошибки в TalkBack - см. событие "Отправить доступность", не связанную для просмотра, для получения дополнительной информации. Если источник события является нулевым, событие игнорируется TalkBack (v3.5.0_r105) и как AccessibilityEvent.setSource(View) Впервые появившись в API 14, до этого нельзя было установить источник - см. проблему без глаз Google № 379

Однако можно заставить Android генерировать такие события, используя View.requestFocus() как я ранее намекнул.

  1. Сделайте ваш View фокусируемым в его XML-макете, используя:

    android:focusable="true"
    android:focusableInTouchMode="true"

  2. Установите устный текст, используя View.setContentDescription(text) в Activity.onCreate или с android:contentDescription="text" в макете XML, если он статический, или динамически в коде, если необходимо.

  3. Когда требуется произносимый текст, переместите фокус на правильный вид, используя View.requestFocus() вызвать AccessibilityEvent,

  4. Чтобы убедиться, что фраза повторяется (мой оригинальный вопрос), позвоните View.clearFocus() прежде чем запрашивать фокус на предыдущем шаге.

У меня есть протестированная реализация этого подхода, работающего на API 8, и он также работает на API 16. Он должен работать вплоть до API 4, когда впервые был доступен API доступности.

Это решение может не потребоваться разработчикам, которые поддерживают только более поздние API Android (14 и более поздние версии), но я полагаю, что в настоящее время существует несколько других вариантов для тех, кто поддерживает специальные возможности в более ранних API. Удачи.

Обновить

К сожалению, ответ alanv, похоже, исчез - возможно, удален - с учетом всех связанных с ним деталей и обсуждения в комментариях. Я попытался вернуть основные моменты ниже.

  1. Для Android API 14 и более поздних версий можно создавать сфокусированные события следующим образом:

    if (mAccessibilityService.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_VIEW_FOCUSED); event.setSource(myView); // API 14 & later event.setClassName(myView.getClass().getName()); event.setPackageName(myView.getContext().getPackageName()); event.setEnabled(true); event.setContentDescription(text); myView.sendAccessibilityEventUnchecked(event); }

  2. Для Android API 16 и более поздних версий View.announceForAccessibility(text) может быть использован.

Другие вопросы по тегам