打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
安卓应用模拟按键事件分发

android应用发送按键事件

模拟按键事件分发

主要用到了以下三种方法:

Instrumentation

标准写法如下,缺点是不能跨进程

	private void sentKey(final int keyCode) {
        Log.d(TAG,"---sentKey---, keyCode : " + keyCode);
        new Thread() {
            public void run() {
                try {
                    Instrumentation inst = new Instrumentation();
                    inst.sendKeyDownUpSync(keyCode);
                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
            }
        }.start();
    }

模拟发送串口命令

参照串口调试执行input keyevent keycode
可跨进程,缺点按键响应时间过长,主观感觉有1-2s

	private void sentKey(int keyCode) {
        try {
            String command = "input keyevent " + keyCode;
            Log.i(TAG, "command = " + command);
            Runtime runtime = Runtime.getRuntime();
            Process proc = runtime.exec(command);
        } catch (IOException e) {
            Log.e(TAG, "Process exec failed!!!");
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }
    }

InputManager类的injectInputEvent(非系统应用)

不能跨进程

 //public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0;
    private void sentKey(int keyCode) {
        Log.d(TAG,"---sentKey---, keyCode : " + keyCode);
        Log.d(TAG,"\n");
        new Thread() {
            public void run() {
                try {

                    long now = SystemClock.uptimeMillis();

                    KeyEvent down =  new KeyEvent(now, now,KeyEvent.ACTION_DOWN, keyCode, 0);
                    KeyEvent up = new KeyEvent(now, now,KeyEvent.ACTION_UP, keyCode, 0);

                    InputManager inputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
                    invokeInjectInputEventMethod(inputManager,down,0);
                    invokeInjectInputEventMethod(inputManager,up,0);

//                    InputManager.getInstance().injectInputEvent(down, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
//                    InputManager.getInstance().injectInputEvent(up, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
                } catch (Exception e) {
                    Log.e(TAG, "Simulate KeyEvent failed !!");
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void invokeInjectInputEventMethod(InputManager inputManager, InputEvent event, int mode) {
        Class<?> clazz = null;
        Method injectInputEventMethod = null;
        Method recycleMethod = null;

        try {
            clazz = Class.forName("android.hardware.input.InputManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try {
            injectInputEventMethod = clazz.getMethod("injectInputEvent", InputEvent.class, int.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            injectInputEventMethod.invoke(inputManager, event, mode);
            // 准备回收event的方法
            recycleMethod = event.getClass().getMethod("recycle");
            //执行event的recycle方法
            recycleMethod.invoke(event);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

InputManager类的injectInputEvent(系统应用)

最终使用的方案,在系统中编译了的,可跨进程,响应时间适中。

 	private void sentKey(int keyCode)  {
//        int actkey = getRcCode(keyCode);
        Log.i(TAG, "sentKey "+keyCode);
        Thread sendKeyEvent = new Thread() {
            @Override
            public void run() {
                try {

                    long now = SystemClock.uptimeMillis();

                    KeyEvent down =  new KeyEvent(now, now,KeyEvent.ACTION_DOWN, keyCode, 0);
                    KeyEvent up = new KeyEvent(now, now,KeyEvent.ACTION_UP, keyCode, 0);

                    InputManager.getInstance().injectInputEvent(down, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
                    InputManager.getInstance().injectInputEvent(up, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);


                } catch (Exception e) {
                    Log.e(TAG, "Simulate KeyEvent failed !!");
                    e.printStackTrace();
                }
            }
        };

        sendKeyEvent.start();
    }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
android 键值控制显示屏 TP调试
Android如何在应用层进行截屏及截屏源码分析(下)
利用input工具发送按键事件
appium+python自动化38-adb按键操作(keyevent)
android edittext 点击回车会响应两次的解决方案
Android WebView的前进、后退、与刷新
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服