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