Оверлей Android для захвата ВСЕХ касаний и передачи их дальше?

Я в основном пытаюсь получить все данные о событиях касания от чего-то вроде системного оверлея, перемещать мои спрайты на основе этих данных касания, а затем позволить ОС/домашнему экрану/браузеру действовать на основе этих данных, как положено (или наоборот). Я нашел похожие вопросы, но ничего, что привело бы меня туда, где я еще не был:

Получение вида, который получает все события касания

(реализовано, результаты ниже) Создание системного оверлейного окна (всегда сверху)

Что я могу сделать:

Я могу ЛИБО перехватывать ВСЕ события касания и действовать в соответствии с ними, перемещая мои спрайты и не позволяя ОС/домашнему экрану/браузеру видеть ни одно из них, ЛИБО я могу позволить событиям касания проходить через них и получать только "TOUCH_OUTSIDE" для моего приложения, чтобы действовать в соответствии с ними.

Моя недостижимая цель:

Я НЕ МОГУ, черт возьми, найти способ заставить ОБОИХ работать с данными. Единственные методы, которые я могу придумать и которые я не могу реализовать, это: перехват данных в моем APP и передача их OS/домашнему экрану/браузеру для работы с ними Позволить ОС/домашнему экрану/браузеру сначала получить данные, а затем получить обратный вызов с информацией каким-то образом Позволить ОС/домашнему экрану/браузеру получить данные, действовать на основе этих данных, а затем опросить их на предмет значений прокрутки/расположения, чтобы действовать на основе этих данных в моем APP.

Я боюсь, что это просто невозможно, мне кажется, я читал где-то в документации, которую сейчас не могу найти: "Все или ничего, либо ваше представление получает все события, либо ни одного"

(Чтобы избежать путаницы, я не имею в виду, что у меня два представления. Я имею в виду, что у меня есть одно представление, управляемое через активность/сервис, наложенный на ОС/домашний экран/браузер. Как стекло, если хотите.)

Спасибо за любую полезную информацию, которую вы можете предложить, это очень ценно!

[UPDATE] Разместил свою собственную документацию по этому вопросу ниже, чтобы не запутаться.

23
задан Community 23 May 2017 в 11:47
поделиться

2 ответа

Нашел эту документацию, которая в значительной степени утверждает, что невозможно сделать и то, и другое: Android: Multi Touch и TYPE_SYSTEM_OVERLAY

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

Чтобы создать вид наложения, при настройке параметров LayoutParams необходимо установить тип TYPE_SYSTEM_OVERLAY и использовать флаг FLAG_WATCH_OUTSIDE_TOUCH. Это создает проблему, потому что, как гласит документация Android: «вы не получите полный жест вниз / перемещение / вверх, только расположение первого вниз как ACTION_OUTSIDE». Чтобы получить полный массив событий касания, вам нужно использовать тип TYPE_SYSTEM_ALERT, но это заставит оверлей захватить экран и прекратить взаимодействие с другими элементами.

Любой, кто хочет не согласиться, хотел бы услышать хорошие новости :-D

15
ответ дан 29 November 2019 в 03:02
поделиться

Я искал то же самое.

Этот флаг помогает мне FLAG_NOT_TOUCH_MODAL

Работает на настройках Android 7 и 8, как показано ниже.

Единственное действие, которое я реализовал до сих пор, - это прикосновение, чтобы закрыть окно наложения.

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

Кстати, Google Maps отлично справляется с этим на Android 8. Вы можете перетаскивать их наложенное окно, изменять его размер или закрывать. И все остальные приложения работают нормально, пока он работает.

    var type = 0

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
    {
        type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
    }
    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    }

    var flags = FLAG_NOT_TOUCH_MODAL

    mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)
1
ответ дан 29 November 2019 в 03:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: