3

I have a view that's always on the screen (over other apps), I wan't to receive touch events and than to pass them farther.

The code from the running Service :

    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,  
            PixelFormat.TRANSLUCENT);

    v.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Toast.makeText(getApplicationContext(), "view touched", Toast.LENGTH_SHORT).show();
            return false;
        }
    });

    WindowManager localWindowManager = (WindowManager)getSystemService("window");
    localWindowManager.addView(v, localLayoutParams);

currently I don't get the touches.

RCB
  • 2,253
  • 2
  • 25
  • 49

2 Answers2

5

You want to declare your view as TYPE_SYSTEM_ALERT, as below:

WindowManager.LayoutParams params =
        new WindowManager.LayoutParams(width, height, x, y,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;

This way it will only respond to touches on the view itself.

This code comes from a working task-switcher that I designed. I did not use FLAG_WATCH_OUTSIDE_TOUCH as it caused problems for me when interacting with other windows below my overlay.


As far as passing the touches on to other apps - that is no longer possible, as it represents a security risk.

I recently put a few more details together on a similar question, which you might find interesting to read:

Also an interesting library mentioned by Edward Jezisek is StandOut by pingpongboss:

Since it is open source, you can go through the code to figure out what he is doing.

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
  • I still don't get the `onTouch` event... and I was able to interact with other apps when I used the `FLAG_WATCH_OUTSIDE_TOUCH` flag – RCB Sep 16 '14 at 11:57
  • 1
    sorry I had a touch listener in another place, that wasn't passing the event further.
    currently I'm trying to overcome the issue of passing the event to the views under mine (that aren't mine). As I understood from your answer I cannot do this. so I'm trying to find a way to simulate a touch event to the system
    – RCB Sep 16 '14 at 12:24
  • There is no solution in the apps you've mentioned, as it's only deals with touch events on it's view and doesn't pass them further. – RCB Sep 16 '14 at 12:35
  • 1
    @RCB Just added those for future readers as it is useful information. As for passing events further - as I said, it is not (should not be) possible without root. – Richard Le Mesurier Sep 16 '14 at 12:42
0

I don't know why, but WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY makes your view not-touchable.

Use WindowManager.LayoutParams.TYPE_PHONE instead.

UPDATE:

I forgot one thing. If you set only WindowManager.LayoutParams.TYPE_PHONE, other app's View will not be touched. So add WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE flag surely.

JK Park
  • 107
  • 8