Служба специальных возможностей: получать представления, с которыми можно мгновенно взаимодействовать (аналогично голосовому доступу)?

Цель состоит в том, чтобы получить представления, с которыми можно взаимодействовать мгновенно (которые можно щелкнуть прямо сейчас, и что-то произойдет). Если представление видимо и кликабельно в целом, но на него наведено другое представление/меню/боковая панель, его следует опустить.

Голосовой доступ сделайте это. И, кажется, использует API доступности.

Прекрасным примером является нижнее меню в Google Maps. Когда он разворачивается, кнопка "Поиск по маршруту" внизу по-прежнему видна, но не подсвечивается приложением.


Итак, что мы имеем?

  • Существует поток AccessibilityEvent. Наиболее полезным является AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, поэтому мы можем получать уведомления, когда что-то происходит.
  • С помощью getSource() мы можем получить экземпляр из AccessibilityNodeInfo, вызвавшего событие. Или мы можем получить корень окна с помощью AccessibilityService.getRootInActiveWindow(). И имея это, мы можем пройти всю иерархию внутри приложения.
  • AccessibilityNodeInfo не предоставляет никакой информации о z-порядке представлений. , так что невозможно понять, что вверху, а что внизу.
  • Нижнее меню находится в том же окне (оно не модальное).
  • Если попытаться нажать кнопку "Искать по маршруту" при развернутом нижнем меню, то нижнее меню сворачивается. Так что вы не можете щелкнуть по нему, он находится под меню.
  • Я просмотрел все параметры AccessibilityNodeInfo, например isVisibleToUser() , isClickable(), isContextClickable(), isSelected(), isFocusable(), isFocused(), isAccessibilityFocused() и кнопка имеет те же параметры, когда нижнее меню свернуто/раскрыто. Он виден пользователю, может быть сфокусирован и доступен для кликов.

  • Я просмотрел скрытые API и не вижу ничего полезного.

Что мне не хватает?


введите описание изображения здесь


person nicolausYes    schedule 12.06.2019    source источник


Ответы (2)


Ключевым моментом является то, что в AccessibilityService. onAccessibilityEvent() древовидная иерархия не является окончательной. Чтобы получить представления, с которыми в данный момент можно взаимодействовать, AccessibilityService.getRootInActiveWindow() следует вызывать с задержкой.

person nicolausYes    schedule 18.06.2019

Возможно, вам поможет AccessibilityNodeInfo#getDrawingOrder(). Обратите внимание, что вам нужно выполнить обход дерева, чтобы определить, что находится поверх чего.

Есть все еще крайние случаи с прозрачными представлениями, которые доставят вам проблемы, но это должно помочь вам в 95% пути. Мы работаем над лучшим ответом для этого случая.

person Phil Weaver    schedule 18.06.2019