TV获取按键只需
Instrumentation mInst = new Instrumentation(); mInst.sendKeyDownUpSync(KeyEvent.KEYCODE_A); //按键事件
这两句. KeyEvent.KEYCODE_A替换成自己的按键需求
1. 使用Instrumentation
new Thread(new Runnable() {
@Override
public void run() {
Instrumentation mInst = new Instrumentation();
mInst.sendKeyDownUpSync(KeyEvent.KEYCODE_A); //按键事件
}
}).start();
或者
public static void simulateKeyEvent(final int KeyCode) {
new Thread(new Runnable() {
public void run() {
// 开线程调用方法
try {
Instrumentation inst=new Instrumentation();
inst.sendKeyDownUpSync(KeyCode);
} catch (Exception e) {
// 异常catch
}
}
}).start();
}
上面介绍的简单方法以Service的形式开启,在单个进程和单个应用中使用是没有问题的,但是当按Home键或者其他方式退出当前应用之后,虽然service还在,但是上述的方法无法执行:Injecting to another application requires INJECT_EVENTS permission,
提示没有权限,但是在AndroidManifest.xml中加上权限之后,仍然无法解决问题。
解决方法
解决该问题的关键是为当前应用的id变成系统级别的,可以理解成获取系统权限,解决方法围绕这点展开
- 在应用程序的AndroidManifest.xml中的manifest节点中加入
android:sharedUserId=”android.uid.system”这个属性。 - 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
- 源码下使用mm命令来编译,生成的apk就有系统的权限。
其中第2\3步,可以 替换成:使用 系统级的 keystore加入项目 即可
查看sendPointerSync()
方法的源码会看到,它使用的是 injectInputEvent()
方法实现:
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
InputManager.getInstance().injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
使用Instrumentation需要<uses-permission android:name="android.permission.INJECT_EVENTS"/>
权限,并且跨App注入事件需要系统应用(AndroidManifest.xml 中加入android:sharedUserId="android.uid.system"
)并且平台签名才行。
2. 使用反射直接调用injectInputEvent()
方法:
private void invokeInjectInputEvent(MotionEvent event) {
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, 0);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}catch (InvocationTargetException e) {
e.printStackTrace();
}
}
3.使用Runtime.exec 执行
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String cmd = "/system/bin/input tap point.x point.y\n";
os.writeBytes(cmd);
os.writeBytes("exit\n");
os.flush();
os.close();
process.waitFor();
或者直接:
Runtime.getRuntime().exec(new String[] {"su", "-c", "input tap " + point.x + " " + point.y});
4. 针对特定的应用可以使用Android Accessibility
5. 可以直接使用Adb shell
adb shell input tap point.x point.y
6.monkeyrunner是一个功能更为丰富的选项,不过需要连接电脑
参考链接:
1. http://azard.me/blog/2015/06/13/android-cross-app-touch-event-injection/
2. http://blog.csdn.net/mad1989/article/details/38109689
3. http://www.race604.com/android-inject-input-event/
原文转载自:https://blog.csdn.net/u014748504/article/details/79172155