覆盖应用程序的反应仅适用于某些触摸事件 [英] Overlay App that reacts only on some touch events

查看:131
本文介绍了覆盖应用程序的反应仅适用于某些触摸事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前潜入Android开发,最近碰到了困难。我想建立一个覆盖应用程序,它位于所有其他应用程序之上。它应该听三指轻扫,而所有其他的触摸事件应该由操作系统(例如一个潜在的应用程序)来处理。

I'm currently diving into Android development and recently came up against a difficulty. I'd like to create an overlay app, which lies on top of all other apps. It should listen for a three finger swipe, whereas all other Touch Events should be handled by the OS (e.g. an underlying app).

是,即使可能吗?

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

I already found out that I need to add the LayoutParam TYPE_PHONE instead of SYSTEM_ALERT since the latter one will consume all touch events. So my class looks like this now:

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所有其他用户交互,直到我杀的应用程序。

The detector will correctly detect a 3 finger swipe but my app in its current state will block all other user interaction with the underlying UI until I kill the app.

有没有系统调用可以与MotionEvent被称为参数在我的TODO注释是现在呢?或做我想要的东西是不可能的?

Is there any system call that can be called with MotionEvent as parameter where my TODO annotation is now? Or do I want something that is just not possible?

最好的问候,并非常感谢你!

Best regards and thank you very much!

修改
该ThreeFingerSwipeDetector类看起来是这样的:

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

其实这不是一个刷卡识别尚未但是它只检查三指水龙头现在。反正在那里的逻辑应该是相当一致的。

Actually it's not a swipe recognizer yet but it only checks for three finger taps for now. Anyways the logic in there should be quite the same.

推荐答案

我会回答我的问题:这是根本不可能的。据<一个href=\"http://stackoverflow.com/questions/9085022/android-overlay-to-grab-all-touch-and-pass-them-on?lq=1\">THIS哨所和Android文档,你可以消耗,因为4.0.3版本的所有触摸事件或无。因此,它不可能只处理一些触摸事件,并让别人去通过覆盖。

I'll answer my own question: It's simply not possible. According to THIS post and the Android documentation you can either consume all touch events or none since version 4.0.3. So it's not possible to handle only some touch events and to let others go through the overlay.

这篇关于覆盖应用程序的反应仅适用于某些触摸事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆