Android : Multi touch and TYPE_SYSTEM_OVERLAY
Solution 1
To create an overlay view, when setting up the LayoutParams
you need to set the type to TYPE_SYSTEM_OVERLAY
and use the flag FLAG_WATCH_OUTSIDE_TOUCH
. This presents a problem because as the Android documentation states:
you will not receive the full down/move/up gesture, only the location of the first down as an
ACTION_OUTSIDE
.
In order to receive the full array of touch events you need to use the TYPE_SYSTEM_ALERT
type, but this causes the overlay to take over the screen and stop interaction with other elements. The solution is to use both TYPE_SYSTEM_OVERLAY
and TYPE_SYSTEM_ALERT
and switch between them by changing the type of the LayoutParams
as needed.
This is accomplished by:
- Watch for the
ACTION_OUTSIDE
motion event. - When it occurs, test if it occured within the overlay.
- If it did, switch the
LayoutParams
type toTYPE_SYSTEM_ALERT
- Once the interaction with the overlay is complete, switch back to
TYPE_SYSTEM_OVERLAY
- Repeat
The one thing to keep in mind is that the ACTION_OUTSIDE
motion event is always passed on to the rest of the elements on the screen. So, for example, if the overlay is on top of a button, that button will also receive the motion event and there is no way to stop it.
Also make sure you add the SYSTEM_ALERT_WINDOW
permission to the mainifest file.
I've posted the complete solution here:
http://www.jawsware.mobi/code_OverlayView/ (UPDATED)
It includes all the source code and a link to download the entire example project.
Update for Android 4.0 - 1/3/2013
To create an overlay view, when setting up the LayoutParams DON'T set the type to TYPE_SYSTEM_OVERLAY
.
Instead set it to TYPE_PHONE
.
Use the following flags:
FLAG_NOT_TOUCH_MODAL
FLAG_WATCH_OUTSIDE_TOUCH
FLAG_NOT_TOUCH_MODAL
<< I found this one to be quite important. Without it, focus is given to the overlay and soft-key (home, menu, etc.) presses are not passed to the activity below.
Also, the previous link (above) has been updated to reflect this update.
Solution 2
Starting from Android 4.x, Android team Android team fixed a potential security problem by adding a new function adjustWindowParamsLw() in which it will add FLAG_NOT_FOCUSABLE, FLAG_NOT_TOUCHABLE and remove FLAG_WATCH_OUTSIDE_TOUCH flags for TYPE_SYSTEM_OVERLAY window.
That's TYPE_SYSTEM_OVERLAY window won't receive any touch event on ICS platform.
Updated: 2016/5/4 TYPE_TOAST cannot receive touch events on Android 4.0~4.3. It's the same as TYPE_SYSTEM_OVERLAY. On Android 4.4+, TYPE_TOAST removed from the excluded list, so you can use TYPE_TOAST to receive touch events on Android 4.4+ devices.
Ravs
Updated on June 11, 2022Comments
-
Ravs almost 2 years
I am trying to get multiple touch events on a system overlay view, but am only receiving the
MotionEvent.ACTION_OUTSIDE
event.Is there any possible way of getting multiple touch events on a system overlay?
Any examples or links would be very helpful.
-
Ravs over 12 yearsThanks for the update Jawsware. But with your logic also I am not able to see multiple touch events on the overlay. I mean if you keep first finger on screen and then second and then third(without lifting previous ones), we should be able to receive touch events(i.e onTouch() should get called). Is it possible anyway?
-
jawsware over 12 yearsYou won't receive multi-touch info while in the
TYPE_SYSTEM_OVERLAY
state. Once you switch toTYPE_SYSTEM_ALERT
(i.e. lift your finger after pressing inside the overlay) you should receive multi-touch events. I appended\nPOINTERS: " + event.getPointerCount()
to each of theinfo.setText
calls in my sample and the pointer count would increase\decrease as I touched\lifted my fingers. After the first down, I only received move events, but the pointer count still changed. -
Ravs over 12 yearsBut what I want is actually getting multi-touch with TYPE_SYSTEM_OVERLAY. Is that possible anyway?
-
jawsware over 12 yearsI don't see how, because you only receive
ACTION_OUTSIDE
. You won't receive UP/DOWN/MOVE. The only solution I could come up with is the Touch To Activate...Do Something...A Gesture/Button to Deactivate. -
Ravs over 12 yearsYes, you are right Jawsware. We can only receive ACTION_OUTSIDE with a TYPE_SYSTEM_OVERLAY. But is there any way of getting even UP/DOWN/MOVE etc. kind of events on a "TYPE_SYSTEM_OVERLAY" ?
-
jawsware over 12 yearsIt seems
TYPE_SYSTEM_OVERLAY
is not meant to be able to interfere with touch events and as long as the type doesn't change, there doesn't seem to be away intercept touch events. -
Brian about 12 yearsThis is helpful! So what are you suggesting that I use instead of FLAG_WATCH_OUTSIDE_TOUCH to achieve the same functionality before Android 4.0. Is there another flag that should be implemented instead?
-
sdyy almost 10 yearsTYPE_PHONE works like as TYPE_SYSTEM_ALERT, it can not click the button under the layout, not like TYPE_SYSTEM_OVERLAY, in Android 4.4....