叠加应用仅对某些触摸事件做出反应

时间:2014-09-18 16:25:58

标签: java android service overlay multi-touch

我目前正在深入开发Android,最近遇到了困难。我想创建一个叠加应用,它位于所有其他应用之上。它应该侦听三指滑动,而所有其他触摸事件应该由操作系统处理(例如底层应用程序)。

这甚至可能吗?

我已经发现我需要添加LayoutParam TYPE_PHONE而不是SYSTEM_ALERT,因为后者将消耗所有触摸事件。 所以我的班级现在看起来像这样:

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's not a 3 finger swipe (aka the detector doesn't recognize it as one)
// something like super.onInterceptTouchEvent(event) or so?
            }
    }
    }

探测器将正确检测3指滑动但我的应用程序处于当前状态将阻止所有其他用户与底层UI的交互,直到我杀死该应用程序。

是否有可以使用MotionEvent作为参数调用的系统调用,我的TODO注释现在是哪个?或者我想要一些不可能的东西?

致以最诚挚的问候,非常感谢!

修改: ThreeFingerSwipeDetector类看起来像这样:

[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();
}

实际上它还不是一个滑动识别器,但它现在只检查三个手指点击。无论如何,那里的逻辑应该是完全相同的。

1 个答案:

答案 0 :(得分:0)

我会回答我自己的问题:这根本不可能。根据{{​​3}}帖子和Android文档,您可以使用所有触摸事件,也可以从版本4.0.3开始不使用任何触摸事件。因此,不可能只处理一些触摸事件并让其他人通过叠加层。