通过shell命令getevent监听Android系统用户输入事件
2020-07-03 15:02
309 查看
我们是自己的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(); } } } } } } }
相关文章推荐
- 立即获得下载任务完成的消息通知。Android DownloadManager通过注册一个广播监听系统的广播事件完成此操作,在创建广播时候,需要指明过滤器为:DownloadManager.ACTIO
- Android系统中通过shell命令实现wifi的连接控制
- execlp启动android进程命令窗口通过adb shell 进入android 的Linux命令界面,输入am -help看到如下信息: 我们可以通过命令启动android中的
- 破解android的root权限的本质是:在系统中加入一个任何用户都可能用于登陆的su命令。或者说替换掉系统中的su程序,因为系统中的默认su程序需要验证实际用户权限,只有root和 shell用户才
- [Android]通过adb shell input上报命令模拟屏幕点击事件【转】
- [Android]通过adb shell input上报命令模拟屏幕点击事件
- 通过Android系统日志监听程序启动事件
- Android 用户事件输入路径(Message/Event, Dispatch Path)
- android系统(3) android 输入事件处理流程 (上)
- android跨进程事件注入(程序模拟用户输入)
- 【代码】android 通过GPS获取用户地理位置并监听位置变化
- Shell while read命令完成用户的交互输入
- Android 4.0 事件输入(Event Input)系统
- Android系统在超级终端下必会的命令大全(adb shell命令大全)
- Android使用ContentObserver监听数据库变化,截取系统通知用户接收到短信
- Android shell 系统命令
- Android 4.0 事件输入(Event Input)系统
- 【Android测试技巧】01. root后adb shell默认不是root用户时,如何将文件放入手机系统中
- android跨进程事件注入(程序模拟用户输入)
- Android系统在超级终端下必会的命令大全(adb shell命令大全)