Overlay app that only responds to certain touch events

I am currently immersed in Android development and have recently encountered difficulties. I would like to create an overlay application that lies on top of all other applications. He should listen to three fingers, while all other touch events should be handled by the OS (for example, the base application).

Is it possible?

I already figured out that I need to add LayoutParam TYPE_PHONE instead of SYSTEM_ALERT, since the latter will consume all touch events. So my class is as follows:

package [...] public class Overlay extends Service { private TView mView; private ThreeFingerSwipeDetector detector = new ThreeFingerSwipeDetector() { @Override public void onThreeFingerTap() { Toast.makeText(getBaseContext(), "Three Fingers recognized.", Toast.LENGTH_SHORT).show(); } }; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Toast.makeText(getBaseContext(), "Launched! :-)", Toast.LENGTH_SHORT).show(); mView = new TView(this); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, // PHONE, because SYSTEM_ALERT will consume _ALL_ touch events WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.RIGHT | Gravity.TOP; WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.addView(mView, params); } @Override public void onDestroy() { WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.removeView(mView); mView = null; super.onDestroy(); } // inner class class TView extends ViewGroup { public TView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { } @Override public boolean onTouchEvent(MotionEvent event) { if(detector.onTouchEvent(event)) { return true; } //TODO: what am I supposed to do when it not a 3 finger swipe (aka the detector doesn't recognize it as one) // something like super.onInterceptTouchEvent(event) or so? } } } 

The detector will correctly recognize three fingers, but my application in its current state will block all other user interactions with the main user interface until I kill the application.

Is there any system call that can be called using MotionEvent as a parameter, where is my TODO annotation now? Or do I want something that is simply impossible?

Best wishes and thank you!

Edit : The ThreeFingerSwipeDetector class looks like this:

 [Import, ...] public abstract class ThreeFingerSwipeDetector { public boolean onTouchEvent(MotionEvent event) { int t = event.getActionMasked(); switch(event.getActionMasked()) { case MotionEvent.ACTION_POINTER_DOWN: if(event.getPointerCount() == 3) onThreeFingerTap(); return true; case MotionEvent.ACTION_DOWN: if(event.getPointerCount() == 3) { onThreeFingerTap(); return true; } } return false; } public abstract void onThreeFingerTap(); } 

In fact, it is still not recognizing wipes, but at the moment it checks only three fingers. In any case, the logic there should be the same.

+2
source share
1 answer

I will answer my question: this is simply impossible. According to the IT post and the Android documentation, you can either use all touch events or not since version 4.0.3. Thus, it is not possible to process only some touch events and allow others to go through the overlay.

0
source

Source: https://habr.com/ru/post/975850/


All Articles