我们是自己的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;}@Overridepublic 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();}}}}}}}