Как получить доступ к AccessibilityNode и выполнить щелчок по дополнительному дисплею в настройке нескольких дисплеев Android?

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

Мне удалось выполнить эту часть, настроив службу, которая использует приложения с использованием разрешения android.permission.SYSTEM_ALERT_WINDOW ( Settings.canDrawOverlays()). Он рисует сенсорную область на первом дисплее (тачбар) и курсор на дополнительном дисплее. Когда пользователь перетаскивает сенсорную панель, курсор перемещается. Я могу получить координаты курсора на дополнительном дисплее, чтобы в любой момент знать, где находится курсор.

Теперь проблема заключается в реализации взаимодействия с щелчками. Мой план состоял в том, чтобы сделать эту службу как AccessibilityService, чтобы я мог выполнять щелчки на «дисплее презентации», когда пользователь нажимает на «дисплей сенсорной панели», но я не могу получить доступ к AccessibilityNode со вторичного дисплея, я могу получить доступ только к текущему активному отображение через « rootInActiveWindow ».

Вот текущий код (имейте в виду, что он находится в области действия AccessibilityService ) :

      private fun click(action: Int = AccessibilityNodeInfo.ACTION_CLICK) {
    val nodeInfo = if(displayManager.displays.size > 1){
        windowsOnAllDisplays.get(displayManager.displays[1].displayId, emptyList()).firstOrNull()?.root ?: rootInActiveWindow
    } else {
        rootInActiveWindow
    } ?: return
    val nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, cursorLayout.x, cursorLayout.y)
    if (nearestNodeToMouse != null) {
        logNodeHierachy(nearestNodeToMouse, 0)
        nearestNodeToMouse.performAction(action)
    }
    nodeInfo.recycle()
}

private fun findSmallestNodeAtPoint(sourceNode: AccessibilityNodeInfo, x: Int, y: Int): AccessibilityNodeInfo? {
    val bounds = Rect()
    sourceNode.getBoundsInScreen(bounds)
    if (!bounds.contains(x, y)) {
        return null
    }
    for (i in 0 until sourceNode.childCount) {
        val child = sourceNode.getChild(i)
        if(child != null) {
            val nearestSmaller = findSmallestNodeAtPoint(child, x, y)
            if (nearestSmaller != null) {
                return nearestSmaller
            }
        }
    }
    return sourceNode
}

Итак, проблема связана с поставщиками « rootInActiveWindow » и « windowsOnAllDisplays ». Для меня windowsOnAllDisplays всегда возвращает пустой список (поэтому я не могу получить доступ к окну на дополнительном дисплее), а « rootInActiveWindow » возвращает только корень текущего активного дисплея (который всегда является дисплеем «сенсорной панели»).

Вот пример приложения на эмуляторе с двумя дисплеями (внизу — первый дисплей (сенсорная панель), сверху — дополнительный дисплей с курсором).

Есть ли у вас какие-либо идеи, как я могу получить доступ к AccessibilityNode со вторичного дисплея, чтобы иметь возможность выполнять щелчок, или даже совершенно другую идею о том, как этого добиться?

0 ответов