android 平台模拟按键转发学习

  在android平台通常需要通过按键来实现一些快捷功能,可以通过模拟按键来完成对应功能。
例如hardware/power/power.cpp 中
bool sendPowerKeyToAndroid() 
{
    int fd = 0;
    int ret = 0;
    int version = 0;
    FILE * deviceInfoFd = NULL;
    char buffer[LINE_MAX_LEN];
    char path[PATH_MAX_LEN] = {0};
    char * ptr = NULL;
    bool found = false;
    //POWER key, see input.h  
    // #define KEY_POWER	116 = 0x74
    struct input_event event[5] = {
        {{0x0, 0x0}, 0x4, 0x4, 0xff},
        {{0x0, 0x0}, 0x1, 0x74, 0x1},
        {{0x0, 0x0}, 0x0, 0x0, 0x0},
        {{0x0, 0x0}, 0x1, 0x74, 0x0},
        {{0x0, 0x0}, 0x0, 0x0, 0x0}};

 deviceInfoFd = fopen(INPUT_DEVICE_INFO_FILE_PATH, "r");
    if (deviceInfoFd == NULL) {
        return false;
    }

    while (fgets(buffer, LINE_MAX_LEN, deviceInfoFd) != NULL) {
        if (strstr(buffer, IR_DEVICE_NAME) != NULL) {
            found = true;
        }
        if ((found == true) && (strstr(buffer, "Handlers") != NULL)) {
            ptr = strstr(buffer, "event");
            if (ptr == NULL) {
                return false;
            }
            sprintf(path, "%s%s", INPUT_DEVICE_PATH, ptr);
            // strip space and '\n'
            for (int pos = strlen(path) - 1; pos >= 0; pos--) {
                if ((path[pos] == '\n') || (path[pos] == ' ')) {
                    path[pos] = '\0';
                }
            }
            break;
        }
    }
    fclose(deviceInfoFd);

    fd = open(path, O_RDWR);
    if (fd < 0) {
        ALOGD("sendPowerKeyToAndroid could not open /dev/input/event0, %s\n", strerror(errno));
        return false;
    }

    if (ioctl(fd, EVIOCGVERSION, &version)) {
        ALOGD("sendPowerKeyToAndroid could not get driver version for /dev/input/event0, %s\n", strerror(errno));
        return false;
    }

    ret = write(fd, &event, sizeof(input_event)*5);
    if (ret < (int)sizeof(input_event)*5) {
        ALOGD("sendPowerKeyToAndroid write event failed, %s\n", strerror(errno));
        return false;
    } else {
        ALOGD("sendPowerKeyToAndroid write event success \n");
    }

    if (close(fd) < 0) {
        ALOGD("sendPowerKeyToAndroid could not close /dev/input/event0, %s\n", strerror(errno));
        return false;
    }

    return true;
}
#define EVIOCGVERSION       _IOR('E', 0x01, int)            /* get driver version */
#define INPUT_DEVICE_INFO_FILE_PATH "/proc/bus/input/devices"
#define INPUT_DEVICE_PATH "/dev/input/"
#define IR_DEVICE_NAME "MStar Smart TV IR Receiver"
#define LINE_MAX_LEN 1024
#define PATH_MAX_LEN 64

解析节点

打开节点/proc/bus/input/devices,解析Handlers键值,
此处为“kbd event1”
在这里插入图片描述

遥控器事件节点

        if ((found == true) && (strstr(buffer, "Handlers") != NULL)) {
            ptr = strstr(buffer, "event");
            if (ptr == NULL) {
                return false;
            }
            sprintf(path, "%s%s", INPUT_DEVICE_PATH, ptr);
            // strip space and '\n'
            for (int pos = strlen(path) - 1; pos >= 0; pos--) {
                if ((path[pos] == '\n') || (path[pos] == ' ')) {
                    path[pos] = '\0';
                }
            }
            break;
        }

将“/dev/input/” 和 “event1” 拼接得到 /dev/input/event1 即为遥控器设备节点。

封装按键信息

	struct input_event
	{
	    struct timeval time;
	    __u16 type;
	    __u16 code;
	    __s32 value;
	};
    struct input_event event[5] = {
        {{0x0, 0x0}, 0x4, 0x4, 0xff},
        {{0x0, 0x0}, 0x1, 0x74, 0x1},
        {{0x0, 0x0}, 0x0, 0x0, 0x0},
        {{0x0, 0x0}, 0x1, 0x74, 0x0},
        {{0x0, 0x0}, 0x0, 0x0, 0x0}};

例如平台捕获power 键,键值信息如下:
在这里插入图片描述
事件类型,事件码,键值,已经按键顺序。
在这里插入图片描述

发送按键

封装好的有序event 信息,往节点发送接口。

    ret = write(fd, &event, sizeof(input_event)*5);
    if (ret < (int)sizeof(input_event)*5) {
        ALOGD("sendPowerKeyToAndroid write event failed, %s\n", strerror(errno));
        return false;
    } else {
        ALOGD("sendPowerKeyToAndroid write event success \n");
    }

举一反三,我们可以通过对输入设备(ir,touch,keyboard…)
发送模拟事件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值