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

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

я могу включить Настройки - > Доступность - >Talkback С Исследуйте На Ощупь из настроек Talkback, а затем одним нажатием на вид, чтобы прочитать ContentDescription вслух.

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

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

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

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

обновление

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

в настоящее время я работаю над решением, которое использует View.clearFocus() следовал по View.requestFocus() чтобы обойти проблему с обновленным представлением. Это, похоже, работает до сих пор на моем тестовом наборе с APIs 8 и 16.

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

1 ответов


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

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

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

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

  1. сделайте свой взгляд фокусируемым в его XML layout использование:

    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) можно использовать.