下面列出了怎么用android.view.InputDevice的API类实例代码及写法,或者点击链接到github查看源代码。
public void injectTouchEventRelease(int x, int y)
{
MotionEvent me = MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis()+10,
MotionEvent.ACTION_UP,
x,
y,
0
);
if(Integer.valueOf(android.os.Build.VERSION.SDK_INT) < android.os.Build.VERSION_CODES.JELLY_BEAN)
;
else
me.setSource(InputDevice.SOURCE_TOUCHSCREEN);
injectEvent(me, INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT);
me.recycle();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 12) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL: {
if (mTouchMode == TOUCH_MODE_REST) {
final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vscroll != 0) {
final int delta = (int) (vscroll * getVerticalScrollFactor());
if (!trackMotionScroll(delta, delta)) {
return true;
}
}
}
}
}
}
}
return super.onGenericMotionEvent(event);
}
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int source = event.getSource();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(event);
newEvent.setTime(downTime, eventTime);
newEvent.setSource(source);
newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
* Send keys and blocks until the first specified accessibility event.
*
* Most key presses will cause some UI change to occur. If the device is busy, this will
* block until the device begins to process the key press at which point the call returns
* and normal wait for idle processing may begin. If no events are detected for the
* timeout period specified, the call will return anyway with false.
*
* @param keyCode
* @param metaState
* @param eventType
* @param timeout
* @return true if events is received, otherwise false.
*/
public boolean sendKeyAndWaitForEvent(final int keyCode, final int metaState,
final int eventType, long timeout) {
Runnable command = new Runnable() {
@Override
public void run() {
final long eventTime = SystemClock.uptimeMillis();
KeyEvent downEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
InputDevice.SOURCE_KEYBOARD);
if (injectEventSync(downEvent)) {
KeyEvent upEvent = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP,
keyCode, 0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
InputDevice.SOURCE_KEYBOARD);
injectEventSync(upEvent);
}
}
};
return runAndWaitForEvents(command, new WaitForAnyEventPredicate(eventType), timeout)
!= null;
}
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (view != getView()) {
return false;
}
boolean consumed = false;
int source = event.getSource();
// logger.log(Level.INFO, "onKey source: {0}", source);
boolean isTouch =
((source & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN) ||
((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD);
// logger.log(Level.INFO, "onKey source: {0}, isTouch: {1}",
// new Object[]{source, isTouch});
if (touchInput != null) {
consumed = touchInput.onKey(event);
}
return consumed;
}
/**
* @see View#onGenericMotionEvent(MotionEvent)
*/
public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
nativeSendMouseWheelEvent(mNativeContentViewCore, event.getEventTime(),
event.getX(), event.getY(),
event.getAxisValue(MotionEvent.AXIS_VSCROLL));
mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
// Send a delayed onMouseMove event so that we end
// up hovering over the right position after the scroll.
final MotionEvent eventFakeMouseMove = MotionEvent.obtain(event);
mFakeMouseMoveRunnable = new Runnable() {
@Override
public void run() {
onHoverEvent(eventFakeMouseMove);
}
};
mContainerView.postDelayed(mFakeMouseMoveRunnable, 250);
return true;
}
}
return mContainerViewInternals.super_onGenericMotionEvent(event);
}
private static MotionEvent.PointerProperties[] getPointerProperties(int inputDevice) {
MotionEvent.PointerProperties[] pointerProperties = {new MotionEvent.PointerProperties()};
pointerProperties[0].clear();
pointerProperties[0].id = 0;
switch (inputDevice) {
case InputDevice.SOURCE_MOUSE:
pointerProperties[0].toolType = MotionEvent.TOOL_TYPE_MOUSE;
break;
case InputDevice.SOURCE_STYLUS:
pointerProperties[0].toolType = MotionEvent.TOOL_TYPE_STYLUS;
break;
case InputDevice.SOURCE_TOUCHSCREEN:
pointerProperties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
break;
default:
pointerProperties[0].toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
break;
}
return pointerProperties;
}
@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);
}
}
GamepadDevice(int index, InputDevice inputDevice) {
mDeviceIndex = index;
mDeviceId = inputDevice.getId();
mDeviceName = inputDevice.getName();
mTimestamp = SystemClock.uptimeMillis();
// Get axis ids and initialize axes values.
final List<MotionRange> ranges = inputDevice.getMotionRanges();
mAxes = new int[ranges.size()];
int i = 0;
for (MotionRange range : ranges) {
if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
int axis = range.getAxis();
assert axis < MAX_RAW_AXIS_VALUES;
mAxes[i++] = axis;
}
}
mMappings = GamepadMappings.getMappings(inputDevice, mAxes);
}
@Override
public boolean onTouch(View view, MotionEvent event) {
if (view != getView()) {
return false;
}
boolean consumed = false;
int source = event.getSource();
// logger.log(Level.INFO, "onTouch source: {0}", source);
boolean isTouch = ((source & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN);
// logger.log(Level.INFO, "onTouch source: {0}, isTouch: {1}",
// new Object[]{source, isTouch});
if (isTouch && touchInput != null) {
// send the event to the touch processor
consumed = touchInput.onTouch(event);
}
return consumed;
}
public void handleMessage(Message m) {
switch (m.what) {
case MSG_INJECT_KEY:
final long eventTime = SystemClock.uptimeMillis();
final InputManager inputManager = (InputManager)
XposedHelpers.callStaticMethod(InputManager.class, "getInstance");
int flags = KeyEvent.FLAG_FROM_SYSTEM;
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 50, KeyEvent.ACTION_DOWN, m.arg1, 0,
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_UNKNOWN), 0);
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 25, KeyEvent.ACTION_UP, m.arg1, 0,
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_UNKNOWN), 0);
break;
}
}
/**
* Check for any game controllers that are connected already.
*/
private void checkGameControllers() {
Log.d(TAG, "checkGameControllers");
int[] deviceIds = mInputManager.getInputDeviceIds();
for (int deviceId : deviceIds) {
InputDevice dev = InputDevice.getDevice(deviceId);
int sources = dev.getSources();
// Verify that the device has gamepad buttons, control sticks, or
// both.
if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
|| ((sources & InputDevice.SOURCE_JOYSTICK)
== InputDevice.SOURCE_JOYSTICK)) {
// This device is a game controller. Store its device ID.
if (!mConnectedDevices.contains(deviceId)) {
mConnectedDevices.add(deviceId);
if (mCurrentDeviceId == -1) {
mCurrentDeviceId = deviceId;
mControllerView.setCurrentControllerNumber(dev.getControllerNumber());
mControllerView.invalidate();
}
}
}
}
}
@Override
public boolean onGenericMotion(View view, MotionEvent event) {
if (view != getView()) {
return false;
}
boolean consumed = false;
int source = event.getSource();
// logger.log(Level.INFO, "onGenericMotion source: {0}", source);
boolean isJoystick =
((source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK);
if (isJoystick && joyInput != null) {
// logger.log(Level.INFO, "onGenericMotion source: {0}, isJoystick: {1}",
// new Object[]{source, isJoystick});
// send the event to the touch processor
consumed = consumed || ((AndroidJoyInput14)joyInput).onGenericMotion(event);
}
return consumed;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL: {
final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vscroll < 0) {
pacedScroll(false);
return true;
} else if (vscroll > 0) {
pacedScroll(true);
return true;
}
}
}
}
return super.onGenericMotionEvent(event);
}
/** Helper function to obtain a MotionEvent. */
private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
float x, float y) {
PointerProperties properties = new PointerProperties();
properties.id = 0;
properties.toolType = Configurator.getInstance().getToolType();
PointerCoords coords = new PointerCoords();
coords.pressure = 1;
coords.size = 1;
coords.x = x;
coords.y = y;
return MotionEvent.obtain(downTime, eventTime, action, 1,
new PointerProperties[] { properties }, new PointerCoords[] { coords },
0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
mInputManager.onGenericMotionEvent(event);
// Check that the event came from a joystick or gamepad since a generic
// motion event could be almost anything. API level 18 adds the useful
// event.isFromSource() helper function.
int eventSource = event.getSource();
if ((((eventSource & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
((eventSource & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK))
&& event.getAction() == MotionEvent.ACTION_MOVE) {
int id = event.getDeviceId();
if (-1 != id) {
Ship curShip = getShipForId(id);
if (curShip.onGenericMotionEvent(event)) {
return true;
}
}
}
return super.onGenericMotionEvent(event);
}
@Override
public boolean onMotionEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_SCROLL) {
if (event.getDownTime() >= mLastDownTime) {
mLastDownTime = event.getDownTime();
} else if ((InputDevice.getDevice(event.getDeviceId()).getSources() &
InputDevice.SOURCE_TOUCHPAD) == InputDevice.SOURCE_TOUCHPAD) {
return false;
}
return handleScrollEvent(event);
} else if ((action == MotionEvent.ACTION_HOVER_MOVE) ||
(action == MotionEvent.ACTION_HOVER_ENTER) ||
(action == MotionEvent.ACTION_HOVER_EXIT)) {
return onMouseEvent(event);
} else {
return false;
}
}
public boolean sendKey(int keyCode, int metaState) {
if (DEBUG) {
Log.d(LOG_TAG, "sendKey (" + keyCode + ", " + metaState + ")");
}
final long eventTime = SystemClock.uptimeMillis();
KeyEvent downEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
InputDevice.SOURCE_KEYBOARD);
if (injectEventSync(downEvent)) {
KeyEvent upEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_UP, keyCode, 0, metaState,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
InputDevice.SOURCE_KEYBOARD);
if (injectEventSync(upEvent)) {
return true;
}
}
return false;
}
protected void sendCancelEvent(MotionEvent event) {
if (mHasSendCancelEvent || (event == null && mLastMoveEvent == null)) {
return;
}
if (sDebug) {
Log.d(TAG, "sendCancelEvent()");
}
final MotionEvent last = event == null ? mLastMoveEvent : event;
final long now = SystemClock.uptimeMillis();
final MotionEvent ev =
MotionEvent.obtain(
now, now, MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), 0);
ev.setSource(InputDevice.SOURCE_TOUCHSCREEN);
mHasSendCancelEvent = true;
mHasSendDownEvent = false;
super.dispatchTouchEvent(ev);
ev.recycle();
}
public static void injectKey(final int keyCode) {
Handler handler = (Handler) XposedHelpers.getObjectField(mPhoneWindowManager, "mHandler");
if (handler == null) return;
handler.post(new Runnable() {
@Override
public void run() {
try {
final long eventTime = SystemClock.uptimeMillis();
final InputManager inputManager = (InputManager)
mContext.getSystemService(Context.INPUT_SERVICE);
int flags = KeyEvent.FLAG_FROM_SYSTEM;
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 50, KeyEvent.ACTION_DOWN,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_UNKNOWN), 0);
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 25, KeyEvent.ACTION_UP,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_UNKNOWN), 0);
} catch (Throwable t) {
XposedBridge.log(t);
}
}
});
}
protected void addController(int deviceId, boolean sendEvent) {
try {
InputDevice device = InputDevice.getDevice(deviceId);
if (!isController(device)) return;
String name = device.getName();
AndroidController controller = new AndroidController(deviceId, name);
controllerMap.put(deviceId, controller);
if (sendEvent) {
synchronized (eventQueue) {
AndroidControllerEvent event = eventPool.obtain();
event.type = AndroidControllerEvent.CONNECTED;
event.controller = controller;
eventQueue.add(event);
}
} else {
controllers.add(controller);
}
Gdx.app.log(TAG, "added controller '" + name + "'");
} catch (RuntimeException e) {
// this exception is sometimes thrown by getDevice().
// we can't use this device anyway, so ignore it and move on
}
}
public static GamepadMappings getMappings(InputDevice device, int[] axes) {
GamepadMappings mappings = null;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mappings = getMappings(device.getProductId(), device.getVendorId());
}
if (mappings == null) mappings = getMappings(device.getName());
if (mappings == null) mappings = new UnknownGamepadMappings(axes);
return mappings;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
ensureInitialized();
// Check that the event came from a joystick since a generic motion event
// could be almost anything.
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0
&& event.getAction() == MotionEvent.ACTION_MOVE) {
// Cache the most recently obtained device information.
// The device information may change over time but it can be
// somewhat expensive to query.
if (mLastInputDevice == null || mLastInputDevice.getId() != event.getDeviceId()) {
mLastInputDevice = event.getDevice();
// It's possible for the device id to be invalid.
// In that case, getDevice() will return null.
if (mLastInputDevice == null) {
return false;
}
}
// Ignore joystick while the DPad is pressed to avoid conflicting motions.
if (mDPadState != 0) {
return true;
}
// Process all historical movement samples in the batch.
final int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) {
processJoystickInput(event, i);
}
// Process the current movement sample in the batch.
processJoystickInput(event, -1);
return true;
}
return super.onGenericMotionEvent(event);
}
/**
* Returns an action that double clicks the view.<br>
* <br>
* View preconditions:
*
* <ul>
* <li>must be displayed on screen
* <ul>
*/
public static ViewAction doubleClick() {
return actionWithAssertions(
new GeneralClickAction(
Tap.DOUBLE,
GeneralLocation.CENTER,
Press.FINGER,
InputDevice.SOURCE_UNKNOWN,
MotionEvent.BUTTON_PRIMARY));
}
private boolean touchUp(int x, int y) {
if (DEBUG) {
Log.d(LOG_TAG, "touchUp (" + x + ", " + y + ")");
}
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(
mDownTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
mDownTime = 0;
return injectEventSync(event);
}
@SdkSuppress(minSdkVersion = 14)
@Test
public void rightClickTest() {
onView(withId(R.id.large_view))
.perform(click(InputDevice.SOURCE_MOUSE, MotionEvent.BUTTON_SECONDARY));
onView(withText(R.string.context_item_1_text)).check(matches(isDisplayed()));
onView(withText(R.string.context_item_2_text)).check(matches(isDisplayed()));
onView(withText(R.string.context_item_3_text)).check(matches(isDisplayed()));
}
/**
* @see View#onGenericMotionEvent(MotionEvent)
*/
public boolean onGenericMotionEvent(MotionEvent event) {
if (GamepadList.onGenericMotionEvent(event)) return true;
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_SCROLL:
getEventForwarder().onMouseWheelEvent(event.getEventTime(), event.getX(),
event.getY(), event.getAxisValue(MotionEvent.AXIS_HSCROLL),
event.getAxisValue(MotionEvent.AXIS_VSCROLL),
mRenderCoordinates.getWheelScrollFactor());
return true;
case MotionEvent.ACTION_BUTTON_PRESS:
case MotionEvent.ACTION_BUTTON_RELEASE:
// TODO(mustaq): Should we include MotionEvent.TOOL_TYPE_STYLUS here?
// crbug.com/592082
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
return getEventForwarder().onMouseEvent(event);
}
}
} else if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
if (mJoystickScrollEnabled) {
float velocityX = getFilteredAxisValue(event, MotionEvent.AXIS_X);
float velocityY = getFilteredAxisValue(event, MotionEvent.AXIS_Y);
flingViewport(event.getEventTime(), -velocityX, -velocityY, true);
return true;
}
}
return mContainerViewInternals.super_onGenericMotionEvent(event);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Note! we are programmatically construction the map view
//be sure to handle application lifecycle correct (see note in on pause)
mMapView = new MapView(inflater.getContext());
mMapView.setDestroyMode(false);
mMapView.setTag("mapView"); // needed for OpenStreetMapViewTest
mMapView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
/**
* mouse wheel zooming ftw
* http://stackoverflow.com/questions/11024809/how-can-my-view-respond-to-a-mousewheel
* @param v
* @param event
* @return
*/
@Override
public boolean onGenericMotion(View v, MotionEvent event) {
if (0 != (event.getSource() & InputDevice.SOURCE_CLASS_POINTER)) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f)
mMapView.getController().zoomOut();
else {
//this part just centers the map on the current mouse location before the zoom action occurs
IGeoPoint iGeoPoint = mMapView.getProjection().fromPixels((int) event.getX(), (int) event.getY());
mMapView.getController().animateTo(iGeoPoint);
mMapView.getController().zoomIn();
}
return true;
}
}
return false;
}
});
return mMapView;
}
static void injectKeyEvent(long time, int action, int keycode, int repeat) {
KeyEvent keyEvent = KeyEvent.obtain(time, time, action, keycode,
repeat, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
InputDevice.SOURCE_HDMI, null);
InputManager.getInstance().injectInputEvent(keyEvent,
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
keyEvent.recycle();
}
@Override // Binder call
public int isInTabletMode() {
if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE,
"isInTabletMode()")) {
throw new SecurityException("Requires TABLET_MODE permission");
}
return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE);
}