Android空闲自定义
目的
检测android是否有输入事件,包括屏幕点击和按键。
想法
android事件都是从 dev/input来的。所以遍历读取整个文件夹下面的文件即可。但是需要root权限。
实现
/**
* Os.poll 监听/dev/input/下面的设备节点,有数据可读,表示设备有操作,不是空闲
*/
private void readInput() {
IDLE_LOOP = true;
ThreadPoolUtils.executeInCachePool(() -> {
try {
File file = new File(INPUT_DIR);// /dev/input
File[] child = file.listFiles();
fd = new StructPollfd[child.length];
for (int i = 0; i < fd.length; i++) {
StructPollfd pollfd = new StructPollfd();
try {
FileInputStream inputStream = new FileInputStream(child[i]);
if (inputStreamList == null)
inputStreamList = new LinkedList<>();
inputStreamList.add(inputStream);
pollfd.fd = inputStream.getFD();
pollfd.events = 0x0001;
} catch (FileNotFoundException e) {
LogUtil.e(TAG, "poll error" + e.getMessage());
e.printStackTrace();
// return;
} catch (IOException e) {
LogUtil.e(TAG, "poll error" + e.getMessage());
e.printStackTrace();
}
if (pollfd != null) {
fd[i] = pollfd;
}
}
while (IDLE_LOOP) {
try {
int code = Os.poll(fd, (int) DELAY_TIME);//系统提供的方式,具体实现是linux的pool(2)
if (code > 0) {
for (StructPollfd structPollfd : fd) {
if (structPollfd.revents == structPollfd.events) {//poll表示是那个文件来的事件
FileDescriptor f = structPollfd.fd;
FileInputStream fileInputStream = new FileInputStream(f);
byte[] b = new byte[512];
int n = fileInputStream.read(b);
}
}
readTime = System.currentTimeMillis();// 这里记录事件开始的时间
} else if (code == 0) {
if (callback != null)
callback.idleNow();
}
} catch (ErrnoException e) {
e.printStackTrace();
LogUtil.e(TAG, "poll error" + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
LogUtil.e(TAG, "poll error" + e.getMessage());
e.printStackTrace();
IDLE_LOOP = false;
}
});
}
总结
还可以使用 adb 命令中的getevent,但是需要一直卡线程。
android.system.OS 这个类里面有不少系统调用,实现都是linux里面的。