2014-09-18 124 views
2

我目前正在潜入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? 
      } 
    } 
    } 

探测器会正确地检测三指轻扫,但我在当前状态下的应用程序将阻止潜在的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(); 
} 

其实它不是一个刷卡识别但但只检查三个手指轻敲现在。无论如何,那里的逻辑应该是完全一样的。

+0

'ThreeFingerSwipeDetector'究竟做什么,代码明智? 'detector.onTouchEvent(event)'目前是否返回'false'?我想它可能不会,这可以解释为什么任何和所有的触摸事件都被使用,直到你杀死你的应用程序。或者,您可能想通过重写'onInterceptTouchEvent()'而不是'onTouchEvent()'来决定是否通过触摸事件做某件事。 – 2014-09-19 09:07:27

+0

所以我在原来的文章中加入了'ThreeFingerSwipeDetector'。它不能识别一个滑动,但还是三个手指敲击,但现在不应该改变任何东西。我也调试了它,当我用少于3个手指触摸屏幕时,它实际上返回了错误。当我覆盖'onInterceptTouchEvent(Event event)'时,根本没有任何事情发生,因为看起来这个方法只被调用一次而不是'onTouchEvent(Event event)',它被频繁地调用。 – visi0nary 2014-09-19 15:22:37

回答

0

我会回答我自己的问题:这根本不可能。根据THIS文章和Android文档,您可以使用自版本4.0.3以来的所有触摸事件或无。所以不可能只处理一些触摸事件并让其他人通过覆盖。