4

我正在尝试开发一种在服务与某些硬件/远程服务器交互时将触摸事件注入系统的服务。我用谷歌搜索,每个人都建议使用这个InputManager类,引用Monkey作为一个示例项目。

但是,没有getInstance()适合我的方法InputManager!我可以访问的只是文档显示的内容。没有getInstance()方法,最重要的是,没有injectInputEvent()方法。

我的构建目标 SDK 是 Android 4.1.2,我的 AndroidManifest.xml 文件指定目标 SDK 版本为 16(我也尝试将最小目标更改为 16,但没有帮助(另外我想保留它)如果可能的话,在 8 点))。

我到底怎么能InputManager像猴子一样使用?Monkey 使用的方法在哪里,为什么我不能使用它们?

4

3 回答 3

2

您不能将输入事件从其他应用程序注入到一个应用程序。此外,您不能从应用程序内部将事件注入您自己的应用程序。https://groups.google.com/forum/?fromgroups=#!topic/android-developers/N5R9rMJjgzk%5B1-25%5D

如果你想自动化,你可以使用 monkeyrunner 脚本来做同样的事情。

于 2012-11-13T16:35:21.193 回答
1
Class cl = InputManager.class;
try {
    Method method = cl.getMethod("getInstance");
    Object result = method.invoke(cl);
    InputManager im = (InputManager) result;
    method = cl.getMethod("injectInputEvent", InputEvent.class, int.class);
    method.invoke(im, event, 2);
}
catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}  catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
} catch (NoSuchMethodException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}catch (InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
于 2014-07-22T05:25:47.830 回答
0

也许这有点晚了,但可能对将来的参考有所帮助。

方法 1:使用检测对象

Instrumentation instrumentation = new Instrumentation();
instrumentation.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
instrumentation.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));

方法 2:使用带反射的内部 API

此方法使用反射来访问内部 API。

private void injectInputEvent(KeyEvent event) {
    try {
        getInjectInputEvent().invoke(getInputManager(), event, 2);
    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
        e.printStackTrace();
    }
}

private static Method getInjectInputEvent() throws NoSuchMethodException {

    Class<InputManager> cl = InputManager.class;
    Method method = cl.getDeclaredMethod("injectInputEvent", InputEvent.class, int.class);
    method.setAccessible(true);
    return method;
}

private static InputManager getInputManager() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    Class<InputManager> cl = InputManager.class;
    Method method = cl.getDeclaredMethod("getInstance");
    method.setAccessible(true);
    return (InputManager) method.invoke(cl);
}

injectInputEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
injectInputEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));

请注意,方法 1是基于公共 API 的干净解决方案,并且在内部它使用来自方法 2的相同调用。

另请注意,这两种方法都不能从MainThread调用。

于 2017-08-01T09:14:03.130 回答