Android中su执行getevent获取事件延迟的解决方案

最近对Android中input子系统比较感兴趣,在电脑端打开cmd可以利用adb shell getevent实时获取在屏幕上的操作和各种按键事件。于是想写个程序利用root权限,后台su 直接执行getevent命令,可结果总是有延迟。比如手指的点击事件或者按钮的按下事件,需要触发很久才会显示,和adbshell的实时显示不一样。在Google搜索了资料是因为getevent有4K的缓冲区,填满4K数据才会刷新的标准输出中。各方搜索解决方案也没有答案。后来测试时发现getevent有个 -c 选项是自定义显示条数的。在输出指定条数事件后就返回了,如果把c设置成合适的值,然后多次执行这个命令不就能近乎实时的收到事件了吗?而且我比较感兴趣的是实体按键的事件,说干就干,代码如下:

new Thread(new Runnable() {
    @Override
    public void run() {
        PrintWriter pw = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("su");
            pw = new PrintWriter(process.getOutputStream());
            InputStream inStream = process.getInputStream();
            InputStream errStream = process.getErrorStream();
            SequenceInputStream sequenceIs = new SequenceInputStream(inStream, errStream);
            BufferedInputStream bufStream = new BufferedInputStream(sequenceIs);
            Reader reader = new InputStreamReader(bufStream, "UTF-8");
            BufferedReader br = new BufferedReader(reader);

            boolean run = true;
            int index = 0;
            while (run){
                pw.println(CMD);
                pw.flush();
                //Log.i(TAG, "run: 写命令");
                index = 0;

                char[] data = new char[19];
                int pos = 0;
                while ((pos = br.read(data)) != -1){
                    index++;
                    if(index == 4){
                        //Log.i(TAG, "跳过");
                        break;
                    }

                    String line = new String(data);
                    if(line.startsWith("0000")){
                        //Log.i(TAG, "run: 跳过命令分割行");
                        continue;
                    }
                    // 识别键值
                    if(data[7] == 'a' && data[8] == '3' && data[17] == '1'){
                        Log.i(TAG, "run: 下一");
                    }else if(data[7] == 'c' && data[8] == '9'&& data[17] == '1'){
                        Log.i(TAG, "run: 暂停");
                    }else if(data[7] == 'c' && data[8] == '8'&& data[17] == '1'){
                        Log.i(TAG, "run: 开始");
                    }else if(data[7] == 'a' && data[8] == '5'&& data[17] == '1'){
                        Log.i(TAG, "run: 上一");
                    }else {
                        Log.i(TAG, index + "-" + line);
                    }
                    //Log.i(TAG, index + "-" + line);
                }
                //Log.i(TAG, "run: 结束一次");
            }
            pw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }
        }
    }
}).start();

1 条思考于 “Android中su执行getevent获取事件延迟的解决方案

发表评论

邮箱地址不会被公开。 必填项已用*标注