我们是自己的Android设备,想做一个屏保功能,需要获取用户是否触摸屏幕事件,来取消屏保或者延时启动屏保。找了系统相关接口没有找到直接的方法和状态。 苦苦寻找终于发现shell命令有显示用户输入的命令: getevent 于是做个线程执行这个shell命令,发现有输入打印,即发送用户操作广播。
try { process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); os.write(command.getBytes()); os.writeBytes("\n"); os.flush(); os.writeBytes("exit\n"); os.flush(); // 保存执行结果 mReader = new BufferedReader(new InputStreamReader( process.getInputStream()), 1024); String line = null; while (mRunning && (line = mReader.readLine()) != null) { if (!mRunning) { break; } YxLog.d(TAG, ": " + line); if (line.length() == 0) { continue; } // 事件记录 EventManage.getInstance().onTouchEvent(); } } catch (IOException e) { e.printStackTrace(); } finally { if (logcatProc != null) { logcatProc.destroy(); logcatProc = null; } if (mReader != null) { try { mReader.close(); mReader = null; } catch (IOException e) { e.printStackTrace(); } } }开始使用命令: “getevent -rl” 一直监听触摸事件产生,在cmd窗口查看效果稳定。但实际使用中,发现偶尔触摸不会触发代码。经过测试验证后,更换单次监听命令: “getevent -c 1” 解决了监听漏掉事件问题。
附属完整工具类:
/** * @author hardy * @name debug * @class name: * @class describe: 执行shell命令,保存结果到文件 * @time 2019-4-29 17:31:37 * @change * @chang time * @class describe */ public class GetEventTask { private static final String TAG = GetEventTask.class.getSimpleName(); /** * 监听输入事件shell命令 */ // private static final String COMMAND_GET_EVENT = "getevent -rl"; private static final String COMMAND_GET_EVENT = "getevent -c 1"; private volatile static GetEventTask mGetEventTask = null; private LogDumper mLogDumper = null; private String mCurrentCommand = null; private boolean isRunning = false; public static GetEventTask getInstance() { if (mGetEventTask == null) { synchronized (GetEventTask.class) { if (mGetEventTask == null) { mGetEventTask = new GetEventTask(); } } } return mGetEventTask; } private GetEventTask() { } /** * 开始监听事件 */ public void startMonitorEvent() { start(COMMAND_GET_EVENT); } /** * 启动shell命令 * * @param command */ public void start(String command) { if (TextUtils.isEmpty(command) == true) { YxLog.e(TAG, "start --- command is null! "); return; } YxLog.d(TAG, "command = " + command); if (isRunning == true) { // 同一个命令不重复执行 if (mCurrentCommand.equals(command) == true) { YxLog.d(TAG, "start --- command is already run!"); return; } else { stop(); } } if (mLogDumper == null) { mLogDumper = new LogDumper(command); } mLogDumper.start(); mCurrentCommand = command; isRunning = true; } /** * 停止 */ public void stop() { YxLog.d(TAG, "--- stop ---"); if (mLogDumper != null) { mLogDumper.stopLogs(); mLogDumper = null; isRunning = false; } else { YxLog.d(TAG, "stop --- mLogDumper is null!"); } } /** * shell命令执行 */ private class LogDumper extends Thread { private Process logcatProc; private BufferedReader mReader = null; private boolean mRunning = true; String command = null; int count = 0; public LogDumper(String command) { this.command = command; } public void stopLogs() { YxLog.d(TAG, "--- LogDumper stopLogs ---"); mRunning = false; } @Override public void run() { Process process = null; DataOutputStream os = null; while (true) { YxLog.d(TAG, "run --- count = " + count++); try { process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); os.write(command.getBytes()); os.writeBytes("\n"); os.flush(); os.writeBytes("exit\n"); os.flush(); // 保存执行结果 mReader = new BufferedReader(new InputStreamReader( process.getInputStream()), 1024); String line = null; while (mRunning && (line = mReader.readLine()) != null) { if (!mRunning) { break; } YxLog.d(TAG, ": " + line); if (line.length() == 0) { continue; } // 事件记录 EventManage.getInstance().onTouchEvent(); } } catch (IOException e) { e.printStackTrace(); } finally { if (logcatProc != null) { logcatProc.destroy(); logcatProc = null; } if (mReader != null) { try { mReader.close(); mReader = null; } catch (IOException e) { e.printStackTrace(); } } } } } } }