下面列出了怎么用android.view.InputEvent的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void onInputEvent(InputEvent event, int displayId) {
try {
if (event instanceof MotionEvent
&& (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
final MotionEvent motionEvent = (MotionEvent) event;
PointerEventListener[] listeners;
synchronized (mListeners) {
if (mListenersArray == null) {
mListenersArray = new PointerEventListener[mListeners.size()];
mListeners.toArray(mListenersArray);
}
listeners = mListenersArray;
}
for (int i = 0; i < listeners.length; ++i) {
listeners[i].onPointerEvent(motionEvent, displayId);
}
}
} finally {
finishInputEvent(event, false);
}
}
int sendInputEventOnMainLooperLocked(PendingEvent p) {
if (mCurChannel != null) {
if (mCurSender == null) {
mCurSender = new ImeInputEventSender(mCurChannel, mH.getLooper());
}
final InputEvent event = p.mEvent;
final int seq = event.getSequenceNumber();
if (mCurSender.sendInputEvent(seq, event)) {
mPendingEvents.put(seq, p);
Trace.traceCounter(Trace.TRACE_TAG_INPUT, PENDING_EVENT_COUNTER,
mPendingEvents.size());
Message msg = mH.obtainMessage(MSG_TIMEOUT_INPUT_EVENT, seq, 0, p);
msg.setAsynchronous(true);
mH.sendMessageDelayed(msg, INPUT_METHOD_NOT_RESPONDING_TIMEOUT);
return DISPATCH_IN_PROGRESS;
}
Log.w(TAG, "Unable to send input event to IME: "
+ mCurId + " dropping: " + event);
}
return DISPATCH_NOT_HANDLED;
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
if (mInputMethodSession == null) {
// The session has been finished.
finishInputEvent(event, false);
return;
}
final int seq = event.getSequenceNumber();
mPendingEvents.put(seq, event);
if (event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent)event;
mInputMethodSession.dispatchKeyEvent(seq, keyEvent, this);
} else {
MotionEvent motionEvent = (MotionEvent)event;
if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) {
mInputMethodSession.dispatchTrackballEvent(seq, motionEvent, this);
} else {
mInputMethodSession.dispatchGenericMotionEvent(seq, motionEvent, this);
}
}
}
@Override
public boolean injectInputEvent(InputEvent event, boolean sync) {
synchronized (mLock) {
throwIfCalledByNotTrustedUidLocked();
throwIfShutdownLocked();
throwIfNotConnectedLocked();
}
final int mode = (sync) ? InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
: InputManager.INJECT_INPUT_EVENT_MODE_ASYNC;
final long identity = Binder.clearCallingIdentity();
try {
return InputManager.getInstance().injectInputEvent(event, mode);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
/**
* A method for injecting an arbitrary input event.
* <p>
* <strong>Note:</strong> It is caller's responsibility to recycle the event.
* </p>
* @param event The event to inject.
* @param sync Whether to inject the event synchronously.
* @return Whether event injection succeeded.
*/
public boolean injectInputEvent(InputEvent event, boolean sync) {
synchronized (mLock) {
throwIfNotConnectedLocked();
}
try {
if (DEBUG) {
Log.i(LOG_TAG, "Injecting: " + event + " sync: " + sync);
}
// Calling out without a lock held.
return mUiAutomationConnection.injectInputEvent(event, sync);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error while injecting input event!", re);
}
return false;
}
public static void hook(ClassLoader loader) {
final Class<?> CLASS_POINTER_EVENT_DISPATCHER = XposedHelpers.findClass(POINTER_EVENT_DISPATCHER_PATH, loader);
XposedHelpers.findAndHookMethod(CLASS_POINTER_EVENT_DISPATCHER, "onInputEvent", InputEvent.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
try {
if (param.args[0] instanceof MotionEvent) {
MotionEvent event = (MotionEvent) param.args[0];
//XpLog.i("input x "+event.getX());
//XpLog.i("input y "+event.getY());
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
PhoneWindowManagerHook.gesturesListener.onPointerEvent(event);
}
}
} catch (Exception e) {
XpLog.e(e);
}
}
});
}
@Override
public boolean setEvent(InputEvent event) {
VolumeKeyEvent volumeKeyEvent = (VolumeKeyEvent) event;
if (volumeKeyEvent.getVolumeKeyEventType() == VolumeKeyEvent.VOLUME_KEY_EVENT_NATIVE && volumeKeyEvent.isVolumeKeyEvent()) {
if (volumeKeyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (volumeKeyEvent.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
volumeDownPressed = true;
} else if (volumeKeyEvent.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
volumeUpPressed = true;
}
} else if (volumeKeyEvent.getAction() == KeyEvent.ACTION_UP) {
if (volumeKeyEvent.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
volumeDownPressed = false;
} else if (volumeKeyEvent.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
volumeUpPressed = false;
}
}
return this.isActionModePerformed();
}
return false;
}
private boolean onInterceptInputEvent(InputEvent event) {
if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus + " event " + event);
boolean consumeEvent = (mFadingStatus == IDLE && mBgAlpha == 0);
if (event instanceof KeyEvent) {
if (consumeEvent) {
consumeEvent = isConsumableKey((KeyEvent) event);
}
int keyCode = ((KeyEvent) event).getKeyCode();
// Back key typically means we're leaving the fragment
if (keyCode != KeyEvent.KEYCODE_BACK) {
tickle();
}
} else {
tickle();
}
return consumeEvent;
}
private boolean onInterceptInputEvent(InputEvent event) {
if (DEBUG) Log.v(TAG, "onInterceptInputEvent status " + mFadingStatus + " event " + event);
boolean consumeEvent = (mFadingStatus == IDLE && mBgAlpha == 0);
if (event instanceof KeyEvent) {
if (consumeEvent) {
consumeEvent = isConsumableKey((KeyEvent) event);
}
int keyCode = ((KeyEvent) event).getKeyCode();
// Back key typically means we're leaving the fragment
if (keyCode != KeyEvent.KEYCODE_BACK) {
tickle();
}
} else {
tickle();
}
return consumeEvent;
}
private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
&& mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
&& mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
throw new IllegalArgumentException("mode is invalid");
}
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final int result;
try {
result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode,
INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
} finally {
Binder.restoreCallingIdentity(ident);
}
switch (result) {
case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
throw new SecurityException(
"Injecting to another application requires INJECT_EVENTS permission");
case INPUT_EVENT_INJECTION_SUCCEEDED:
return true;
case INPUT_EVENT_INJECTION_TIMED_OUT:
Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
return false;
case INPUT_EVENT_INJECTION_FAILED:
default:
Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
return false;
}
}
final boolean filterInputEvent(InputEvent event, int policyFlags) {
synchronized (mInputFilterLock) {
if (mInputFilter != null) {
try {
mInputFilter.filterInputEvent(event, policyFlags);
} catch (RemoteException e) {
/* ignore */
}
return false;
}
}
event.recycle();
return true;
}
@Override
public void sendInputEvent(InputEvent event, int policyFlags) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
}
synchronized (mInputFilterLock) {
if (!mDisconnected) {
nativeInjectInputEvent(mPtr, event, Display.DEFAULT_DISPLAY, 0, 0,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
policyFlags | WindowManagerPolicy.FLAG_FILTERED);
}
}
}
/**
* Dispatches an input event to the IME.
*
* Returns {@link #DISPATCH_HANDLED} if the event was handled.
* Returns {@link #DISPATCH_NOT_HANDLED} if the event was not handled.
* Returns {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the
* callback will be invoked later.
*
* @hide
*/
public int dispatchInputEvent(InputEvent event, Object token,
FinishedInputEventCallback callback, Handler handler) {
synchronized (mH) {
if (mCurMethod != null) {
if (event instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent)event;
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN
&& keyEvent.getKeyCode() == KeyEvent.KEYCODE_SYM
&& keyEvent.getRepeatCount() == 0) {
showInputMethodPickerLocked();
return DISPATCH_HANDLED;
}
}
if (DEBUG) Log.v(TAG, "DISPATCH INPUT EVENT: " + mCurMethod);
PendingEvent p = obtainPendingEventLocked(
event, token, mCurId, callback, handler);
if (mMainLooper.isCurrentThread()) {
// Already running on the IMM thread so we can send the event immediately.
return sendInputEventOnMainLooperLocked(p);
}
// Post the event to the IMM thread.
Message msg = mH.obtainMessage(MSG_SEND_INPUT_EVENT, p);
msg.setAsynchronous(true);
mH.sendMessage(msg);
return DISPATCH_IN_PROGRESS;
}
}
return DISPATCH_NOT_HANDLED;
}
private PendingEvent obtainPendingEventLocked(InputEvent event, Object token,
String inputMethodId, FinishedInputEventCallback callback, Handler handler) {
PendingEvent p = mPendingEventPool.acquire();
if (p == null) {
p = new PendingEvent();
}
p.mEvent = event;
p.mToken = token;
p.mInputMethodId = inputMethodId;
p.mCallback = callback;
p.mHandler = handler;
return p;
}
@Override
public void finishedEvent(int seq, boolean handled) {
int index = mPendingEvents.indexOfKey(seq);
if (index >= 0) {
InputEvent event = mPendingEvents.valueAt(index);
mPendingEvents.removeAt(index);
finishInputEvent(event, handled);
}
}
private boolean injectInputEvent(InputEvent event) {
if (mInputForwarder != null) {
try {
return mInputForwarder.forwardEvent(event);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
}
return false;
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (event instanceof MotionEvent
&& (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
dispatchPointer(dup);
handled = true;
}
} finally {
finishInputEvent(event, handled);
}
}
private MotionInjector() throws MotionDrawException {
try {
mInputManager = (InputManager)
InputManager.class.getDeclaredMethod("getInstance").invoke(null);
mInjectInputEvent =
InputManager.class.getDeclaredMethod("injectInputEvent",
InputEvent.class, Integer.TYPE);
mInjectInputEvent.setAccessible(true);
} catch (Exception e) {
throw new MotionDrawException(e.getMessage());
}
}
@SuppressLint("PrivateApi")
public HJInput() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mInputManager = (InputManager) InputManager.class.getDeclaredMethod("getInstance").invoke(null);
mInjectInputEventMethod = InputManager.class.getMethod("injectInputEvent", InputEvent.class, Integer.TYPE);
}
} catch (Exception e) {
HJLog.e(e);
}
}
public boolean injectEventSync(final InputEvent event, boolean shouldRegister) throws UiAutomator2Exception {
if (!shouldRegister) {
return (Boolean) invoke(method(CLASS_INTERACTION_CONTROLLER,
METHOD_INJECT_EVENT_SYNC, InputEvent.class), interactionController, event);
}
return EventRegister.runAndRegisterScrollEvents(new ReturningRunnable<Boolean>() {
@Override
public void run() {
Boolean result = (Boolean) invoke(method(CLASS_INTERACTION_CONTROLLER,
METHOD_INJECT_EVENT_SYNC, InputEvent.class), interactionController, event);
setResult(result);
}
});
}
@Override
public boolean setEvent(InputEvent event) {
VolumeKeyEvent volumeKeyEvent = (VolumeKeyEvent) event;
if (volumeKeyEvent.getVolumeKeyEventType() == VolumeKeyEvent.VOLUME_KEY_EVENT_ROCKER && volumeKeyEvent.isVolumeKeyEvent()) {
buffer[current_ptr] = volumeKeyEvent.getCurrentValue();
current_ptr++;
if (current_ptr == MAX_BUFFER_SIZE) {
current_ptr = 0;
}
return this.isActionModePerformed();
}
return false;
}
private InputDeviceState getInputDeviceState(InputEvent event) {
final int deviceId = event.getDeviceId();
InputDeviceState state = mInputDeviceStates.get(deviceId);
if (state == null) {
final InputDevice device = event.getDevice();
if (device == null) {
return null;
}
state = new InputDeviceState(device);
mInputDeviceStates.put(deviceId, state);
Log.i(TAG, device.toString());
}
return state;
}
public boolean injectInputEvent(InputEvent event, boolean sync) {
return mUiAutomation.injectInputEvent(event, sync);
}
private boolean injectEventSync(InputEvent event) {
return mUiAutomatorBridge.injectInputEvent(event, true);
}
@Override
public void onInputEvent(InputEvent event, int displayId) {
boolean handled = false;
try {
if (!(event instanceof MotionEvent)
|| (event.getSource() & SOURCE_CLASS_POINTER) == 0
|| mMuteInput) {
return;
}
final MotionEvent motionEvent = (MotionEvent) event;
final float newX = motionEvent.getRawX();
final float newY = motionEvent.getRawY();
final boolean isStylusButtonDown =
(motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0;
if (mIsStartEvent) {
// First event and the button was down, check for the button being
// lifted in the future, if that happens we'll drop the item.
mStylusButtonDownAtStart = isStylusButtonDown;
mIsStartEvent = false;
}
switch (motionEvent.getAction()) {
case ACTION_DOWN:
if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
return;
case ACTION_MOVE:
if (mStylusButtonDownAtStart && !isStylusButtonDown) {
if (DEBUG_DRAG) {
Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + ","
+ newY);
}
mMuteInput = true;
}
break;
case ACTION_UP:
if (DEBUG_DRAG) {
Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY);
}
mMuteInput = true;
break;
case ACTION_CANCEL:
if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
mMuteInput = true;
break;
default:
return;
}
mDragDropController.handleMotionEvent(!mMuteInput /* keepHandling */, newX, newY);
handled = true;
} catch (Exception e) {
Slog.e(TAG_WM, "Exception caught by drag handleMotion", e);
} finally {
finishInputEvent(event, handled);
}
}
private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId,
int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
int policyFlags);
@Override // Binder call
public boolean injectInputEvent(InputEvent event, int mode) {
return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode);
}
@Override
public boolean injectInputEvent(InputEvent event, int displayId, int mode) {
return injectInputEventInternal(event, displayId, mode);
}
@Override
public boolean forwardEvent(InputEvent event) {
return mInputManagerInternal.injectInputEvent(event, mDisplayId,
INJECT_INPUT_EVENT_MODE_ASYNC);
}
private void onUnhandledInputEventInternal(WebView view, InputEvent event) {
ViewRootImpl root = view.getViewRootImpl();
if (root != null) {
root.dispatchUnhandledInputEvent(event);
}
}