在 Android 中是否有一种合法的方式来监听用户所做的所有触摸事件,即使是在我的应用程序之外。我的意思是拥有类似在后台监听屏幕手势的服务。
最佳答案
这个想法是定义一个非常小的虚拟 UI fragment (比如 1x1 像素),并将其放置在屏幕的一个角落,让它监听它之外的所有触摸事件。好吧,从字面上看,它不是“隐形”的,事实上它一直在前台!但由于它非常小,所以希望用户不会感到有什么不同。
首先,让我们创建这个虚拟 View :
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mDummyView = new LinearLayout(mContext);
LayoutParams params = new LayoutParams(1, LayoutParams.MATCH_PARENT);
mDummyView.setLayoutParams(params);
mDummyView.setOnTouchListener(this);
这里我们将虚拟 View 的宽度设置为 1 像素,将高度设置为父 View 的高度。我们还设置了这个虚拟 View 的触摸事件监听,稍后我们将实现。
然后让我们添加这个虚拟 View 。
LayoutParams params = new LayoutParams(
1, /* width */
1, /* height */
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE |
LayoutParams.FLAG_NOT_TOUCH_MODAL |
LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSPARENT
);
params.gravity = Gravity.LEFT | Gravity.TOP;
mWindowManager.addView(mDummyView, params);
这里的关键是 FLAG_WATCH_OUTSIDE_TOUCH 标志,它使虚拟 View 能够捕获屏幕上的所有事件,无论事件是否在虚拟 View 内。
最后,让我们通过实现 View.OnTouchListener 监听器来处理触摸事件。
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "Touch event: " + event.toString());
// log it
return false;
}
我们需要返回 false,因为我们并没有真正处理该事件,以便底层的真实 UI 元素可以获取这些事件。
最后要注意的是,为了让我们的虚拟 View 始终监听触摸事件,我们需要将所有这些包装在一个服务中:我们在 onCreate 中创建虚拟 View 并在 onStartCommand 中将其添加到屏幕。服务应该实现 View.OnTouchListener 来接收触摸事件。
引用资料 我从这里得到这个 http://jhshi.me/2014/11/09/monitor-screen-touch-event-in-android/
关于android - 在后台监听触摸事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37432796/