您可以通过执行 Android 附带的 /system/bin/input 实用程序在设备上注入输入事件。您可以在this question 中看到一些使用它的示例(通过 adb)。输入实用程序似乎不需要任何特殊权限即可执行。
要创建系统应用程序,您需要访问在为您的设备构建 Android 操作系统时使用的签名密钥 - 您不能只修改普通应用程序以赋予其系统权限。即使可以,它也不会授予您 root 访问权限(尽管您可能会使其成为 /dev/input/eventX 设备似乎也允许访问的输入用户组的一部分)。
如果要注入触摸事件,可以使用Java Runtime class 的exec() 方法执行/system/bin/input 实用程序,或者只使用InputManager 中的injectMotionEvent() 方法。
以下是从 Android 源代码中获取的方法,展示了如何注入 MotionEvent - 您可以查看完整的 source 以获取更多信息。
/**
* Builds a MotionEvent and injects it into the event stream.
*
* @param inputSource the InputDevice.SOURCE_* sending the input event
* @param action the MotionEvent.ACTION_* for the event
* @param when the value of SystemClock.uptimeMillis() at which the event happened
* @param x x coordinate of event
* @param y y coordinate of event
* @param pressure pressure of event
*/
private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {
final float DEFAULT_SIZE = 1.0f;
final int DEFAULT_META_STATE = 0;
final float DEFAULT_PRECISION_X = 1.0f;
final float DEFAULT_PRECISION_Y = 1.0f;
final int DEFAULT_DEVICE_ID = 0;
final int DEFAULT_EDGE_FLAGS = 0;
MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,
DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID,
DEFAULT_EDGE_FLAGS);
event.setSource(inputSource);
Log.i(TAG, "injectMotionEvent: " + event);
InputManager.getInstance().injectInputEvent(event,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
这些方法只允许您将事件注入您自己的应用程序窗口。
如果您想将事件注入不属于您的应用的其他窗口,您需要在您的应用清单中声明额外的权限(READ_INPUT_STATE 和 INJECT_EVENTS)并使用 Android 操作系统签名密钥为您的应用签名.换句话说,将事件注入其他应用程序所需的权限永远不会授予普通应用程序(原因很明显)。