我目前正在潜入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();
}
其实它不是一个刷卡识别但但只检查三个手指轻敲现在。无论如何,那里的逻辑应该是完全一样的。
'ThreeFingerSwipeDetector'究竟做什么,代码明智? 'detector.onTouchEvent(event)'目前是否返回'false'?我想它可能不会,这可以解释为什么任何和所有的触摸事件都被使用,直到你杀死你的应用程序。或者,您可能想通过重写'onInterceptTouchEvent()'而不是'onTouchEvent()'来决定是否通过触摸事件做某件事。 – 2014-09-19 09:07:27
所以我在原来的文章中加入了'ThreeFingerSwipeDetector'。它不能识别一个滑动,但还是三个手指敲击,但现在不应该改变任何东西。我也调试了它,当我用少于3个手指触摸屏幕时,它实际上返回了错误。当我覆盖'onInterceptTouchEvent(Event event)'时,根本没有任何事情发生,因为看起来这个方法只被调用一次而不是'onTouchEvent(Event event)',它被频繁地调用。 – visi0nary 2014-09-19 15:22:37