Android 10, вводящий входы на внешний / виртуальный дисплей

Концепция:

У меня есть приложение для Android, написанное на Kotlin, которое просто запускает приложение Android на внешнем дисплее. Дисплей может быть AirServer, Miracast, Microsoft Connect, USB-OTG HDMI, USB-C HDMI или смоделированным дополнительным дисплеем (см. Снимок экрана).

Вот исключение из кода, который выполняет "тяжелую работу":

        val intent = packageManager.getLaunchIntentForPackage(info.id)
        val dm = recyclerView.context.getSystemService(Service.DISPLAY_SERVICE) as DisplayManager
        val displays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION)

        for (display in displays) {
            val options = ActivityOptions.makeBasic()
            options.launchDisplayId = display.displayId
            recyclerView.context.startActivity(intent, options.toBundle())
            break
        }

Приложения запускаются нормально. См. Снимок экрана, где я использовал его для запуска Minecraft Pocket Edition на смоделированном дополнительном дисплее (как если бы был подключен внешний монитор HDMI). Проблема в том, что я не могу отправлять сенсорный ввод или ввод курсора на виртуальные дисплеи.

Что работает:

  • adb shell input -d <display-id> tap <x> <y>
  • Беспроводные контроллеры
  • Беспроводные клавиатуры

Что не работает:

  • Беспроводные / проводные мыши (курсор касается краев экрана телефона, никогда не попадает на экран виртуального / внешнего дисплея)
  • Touch (см. Снимок экрана)

Что я пробовал:

Выход dumpsys display показывает, что на всех виртуальных дисплеях отсутствует touch VIRTUALпараметр, который имеет внутренний дисплей. Я не уверен, означает ли это, что сам дисплей не поддерживает ввод с сенсорного экрана, или он просто не включен.

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

Стоит отметить, что настройка разработчика режима рабочего стола Android 10 ДОЛЖНА помещать курсор на внешний дисплей, а не на внутренний. Это то, чего я пытаюсь достичь.

Похоже, что в Android SDK есть скрытый Java API:

https://github.com/aosp-mirror/platform_frameworks_base/blob/a4ddee215e41ea232340c14ef92d6e9f290e5174/services/core/jni/com_android_server_input_InputManagerService.cpp

Я попытался получить доступ к этому классу через отражение и вызвать setFocusedDisplay, но продолжал получать исключения ClassNotFound, даже если были изменены параметры безопасности частного черного списка API.

Любая помощь будет оценена здесь. Единственная другая угроза, связанная с этой, здесь, и она так и не была устранена:

События сенсорного ввода Android Q VirtualDisplay

1 ответ

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

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