使用android.view.InputEventReceiver可以在后台Service中监听系统的所有MotionEvent。
1.实现方法:
private InputMonitor mInputMonitor;
private InputEventReceiver mInputEventReceiver;
private void regiesterToucher() {
InputManager inputManager = getSystemService(InputManager.class);
//这里第二个参数是displayId,需要监听哪个屏幕就传哪个屏id,0是系统默认屏
mInputMonitor = inputManager.monitorGestureInput("Test_toucher", 0);
mInputEventReceiver = new InputEventReceiver(
mInputMonitor.getInputChannel(), Looper.getMainLooper()) {
@Override
public void onInputEvent(InputEvent event) {
Log.d(TAG, "onInputEvent: "+event);
//如果不在这里消耗事件则传递false;
finishInputEvent(event, false /* handled */);
}
};
}
2.注册:
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"onCreate");
regiesterToucher();
}
结合InputMonitor可以把输入管道注册到InputDispatcher中,在InputDispatcher中会生成一个SPY的window(com.android.server.input.GestureMonitorSpyWindow):
Display: 0
logicalSize=1080x1920
transform (ROT_0) (IDENTITY)
Windows:
0: name='[Gesture Monitor] Test_toucher', id=71, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | SPY, alpha=1.00, frame=[0,0][0,0], globalScale=1.000000, applicationInfo.name=[Gesture Monitor] Test_toucher, applicationInfo.token=<null>, touchableRegion=[-10799,-19199][10800,19200], ownerPid=21695, ownerUid=1000, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
从dump信息也可以看出它包含flag NOT_FOCUSABLE,因此它无法接收KeyEvent,因为KeyEvent默认是会发往焦点屏幕中的焦点window。
关于SPY window的说明:
/**
* An input spy window. This window will receive all pointer events within its touchable
* area, but will not stop events from being sent to other windows below it in z-order.
* An input event will be dispatched to all spy windows above the top non-spy window at the
* event's coordinates.
*/
SPY = 1 << 14,
3.释放资源:
@Override
public void onDestroy() {
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
}
if (mInputMonitor != null) {
mInputMonitor.dispose();
mInputMonitor = null;
}
super.onDestroy();
Log.d(TAG,"onDestroy");
}
4.注意配置权限:
android:sharedUserId="android.uid.system"
或者
android.Manifest.permission.MONITOR_INPUT加系统签名;