Android наложение, чтобы захватить ВСЕ касания и передать их? - PullRequest
23 голосов
/ 31 января 2012

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

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

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

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

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

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

Я не могу на всю жизнь найти способ заставить ОБА работать с данными.Единственные способы, о которых я не могу понять, которые я не могу реализовать, это: перехват данных в моем приложении и их передача в ОС / домашний экран / браузер для работы с разрешением ОС / домашнему экрану / браузеру сначала получать данные, а затемКак-то получить обратный вызов с информацией Позволяет ОС / домашнему экрану / браузеру получать данные, воздействовать на данные и опрашивать их, чтобы узнать, каковы их значения прокрутки / местоположения, чтобы воздействовать на них в моем приложении.

Боюсь, что это просто невозможно, мне кажется, я где-то прочитал документацию, которую сейчас не могу найти: «Это все или ничего, либо ваш взгляд получает все события, либо ни одного из них»

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

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

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

Ответы [ 4 ]

15 голосов
/ 01 февраля 2012

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

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

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

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

2 голосов
/ 01 февраля 2012

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

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

1 голос
/ 12 февраля 2018

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

Этот флаг помогает мне 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)
0 голосов
/ 12 июля 2014

Это не оптимальное решение, но оно работает.Перезапустите сервис, переключая флаг, который нельзя коснуться.установите логическое значение 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);
        }
    }
}
...