要实现的功能:在android Framework层被裁剪掉的情况下,实现监听长按的物理power按键,实现长按3秒后关机功能;
从事成都二枢服务器租用托管,服务器租用,云主机,网站空间,域名申请,CDN,网络代维等服务。
思路:使用event epoll,非阻塞式IO操作,同时避免无差别轮询,做到避免忙轮和无差别轮询提高效率;
要用到的epoll函数:
epoll_create(EPOLL_SIZE_HINT); epoll_wait(mEpollFd, mPendingEventItems, 8, -1); epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem) epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, &eventItem);
下面是实现的过程:
int main(int argc, char *argv[]) { ALOGI("robot test robot power"); struct itimerval old_value; int tap_power_time = 0; int tap_power_type = 0; int tap_power_code = 0; int tap_power_value = 0; struct itimerval tick; int mEpollFd; const int EPOLL_SIZE_HINT = 8; const char* DEV_INPUT = "/dev/input/event1"; struct epoll_event mPendingEventItems[8]; unsigned char buf[1024] = {0}; struct inotify_event *event = NULL; struct RawEvent* readBuffer = (struct RawEvent*) malloc (sizeof(struct RawEvent)); mEpollFd = epoll_create(EPOLL_SIZE_HINT); int fd = open(DEV_INPUT, O_RDWR | O_CLOEXEC); /* * struct epoll_event { * uint32_t events; // epoll events (bit mask) * epoll_data_t data; // User data * }; */ struct epoll_event eventItem; memset(&eventItem, 0, sizeof(eventItem)); /** * EPOLLIN: has data to read * EPOLLOUT: has data to write */ eventItem.events = EPOLLIN; /** * EPOLL_CTL_ADD: add fd to watching list * EPOLL_CTL_DEL: remove fd from watching list */ if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem) == -1) { exit(0); } for (;;) { /** * parameter -1 : wait until event occur ; * 0 : return immediately when deal with a non-block event */ epoll_wait(mEpollFd, mPendingEventItems, 8, -1); int32_t readSize = read(fd, readBuffer, sizeof(struct input_event)); struct input_event *event =(struct input_event*) readBuffer; tap_power_time = (int) event->time.tv_sec; tap_power_type = event->type; tap_power_code = event->code; tap_power_value = event->value; if(is_power_down_key(tap_power_type, tap_power_code, tap_power_value)) { ALOGI("robot power down key"); signal(SIGALRM,handle_exit); memset(&tick,0,sizeof(tick)); tick.it_value.tv_sec= 3; tick.it_value.tv_usec= 0; setitimer(ITIMER_REAL,&tick,NULL); } else if(is_power_up_key(tap_power_type, tap_power_code, tap_power_value)) { tick.it_value.tv_sec= 0; tick.it_value.tv_usec= 0; setitimer(ITIMER_REAL,&tick,NULL); } } epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, &eventItem); return 0; }
struct RawEvent { int32_t when; int32_t deviceId; int32_t type; int32_t code; int32_t value; }; void handle_exit(int sig) { ALOGI("robot 3 second time out ,now shutdown!"); system("reboot -p"); } int is_power_down_key(int type, int code, int value) { int is_down = 0; is_down = (type == 1) && (code == 116) && (value == 1); return is_down; } int is_power_up_key(int type, int code, int value) { int is_up = 0; is_up = (type == 1) && (code == 116) && (value == 0); return is_up; }