Подтвердить что ты не робот

Оверлей Android, чтобы захватить ALL touch и передать их?

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

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

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

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

Я могу ЭТО взять все события касания и действовать на них, перемещая мои спрайты и не позволяя OS/homecreen/browser видеть любой из них, ИЛИ ELSE. Я могу позволить событиям касания пройти и получить только "TOUCH_OUTSIDE" для моего приложения.

Моя недостигнутая цель:

Я НЕ МОЖЕТСЯ для жизни, когда я выясняю способ обойти работу с данными. Единственные методы, о которых я могу думать, что я не могу реализовать, - это: Перехват данных в моем APP и передача его на OS/homecreen/browser для работы с Позволяя оператору/домашнему экрану/браузеру сначала получить данные, а затем получить обратный вызов с информацией как-то Разрешение OS/homecreen/browser получать данные, воздействовать на данные и опросить их за то, что их значения прокрутки/местоположения, чтобы воздействовать на него в моем APP.

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

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

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

[ОБНОВЛЕНИЕ] Написал мою собственную документацию по этому вопросу ниже, чтобы не путать.

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Вы можете использовать GestureOverlayView, если вы хотите скрыть линии, которые он рисует, вы можете установить цвет на Transparent # 00000000, чтобы он не отображался, а затем вы можете захватывать все касания и жесты.

http://developer.android.com/resources/articles/gestures.html

Ответ 3

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

Этот флаг помогает мне 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)

Ответ 4

Это не оптимальное решение, но оно работает. Перезапустите сервис, переключая флаг, который нельзя коснуться. установите логическое значение extra в Intent, которое используется для запуска службы для определения предыдущего значения переключения состояния. Лучшей реализацией было бы использование намерения при касании, когда окно слушает, и по истечении определенного периода, когда оно не слушается.

public class bleh extends Service {
    public void onCteqwer(int i) {

        Context context; Class <bleh> context1 = bleh.class;

        WindowManager.LayoutParams params = null;
        WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);

        //check previous state of service
        if(i==0)
            params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);

        if(i==1)
            params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);

        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        View mViw = inflater.inflate(arg, null);

        mViw.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });

        mang.addView(mViw, params);

        Intent z = new Intent(context, context1);

        if(i==0)
            z.putExtra("name", 1);
        if(i==1)
            z.putExtra("name", 0);

        stopSelf();
        startService(z);
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Bundle i=intent.getExtras();
        int userName = 0;

        if (i != null)
        {
            userName = i.getInt("name");
            onCteqwer(userName);
        }
    }
}