最近对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();
你好,我复制你的代码还是有打印不全的问题