现在的位置: 首页 > 综合 > 正文

和菜鸟一起学android4.0.3源码之按键驱动短长按功能

2013年08月12日 ⁄ 综合 ⁄ 共 3528字 ⁄ 字号 评论关闭

      
一切再次回到原点,一切都又开始了正常的路线,上班,下班。每每一个人回到那小小的屋子,觉得什么也不是。想离开,又不知道要去哪。日子还是一天天过去,地球不因任何人改变它的转速,月亮也不会为了谁而改变她的形状。平静,也许就是一种幸福。

      
上周由于其他部门需要用我们的芯片,得模拟个input设备,用以mcu按键传递过来后的处理。所以只能屁颠屁颠地去实现了,还好以前做过类似的驱动,于是很快就实现了这个功能。但是一直对于android长按键功能和短按键功能表示不解。网上也很少讲到驱动时怎么取实现的。一直以为那个

input_report_key(btn_dev, KEY_POWER, 0);

input_report_key(btn_dev, KEY_POWER, 1);

这句话是表示按键的按下和抬起,其实错了,是value值为1的时候表示是按键按下,而value值是0的时候才是表示按键的抬起,而每次都需要发送一个

input_sync(btn_dev);

这样才表示是整个过程,才可以实现按键的长按和短按的功能。也就是下面的方式:

input_report_key(btn_dev, KEY_POWER, 1);

input_sync(btn_dev);

这个表示的是按键被按下了。

input_report_key(btn_dev, KEY_POWER, 0);

input_sync(btn_dev);

这个表示按键被抬起了。

这两个之间是表示按键按下的时间长度,android上层就是通过这个来实现按键的短按和长按的功能的。

下面用简单的驱动和简单的应用才实现android的按键的功能,无需真实的按键就可以测试了。

下面的驱动和我的那篇input子系统实例的驱动很类似

 

#include <linux/slab.h>

#include <linux/irq.h>

#include <linux/interrupt.h>

#include <linux/poll.h>

#include <asm/io.h>

#include <linux/delay.h>

#include <linux/module.h>

#include <linux/time.h>

#include <linux/gpio.h>

#include <linux/wait.h>

#include <linux/input.h>

#include <linux/init.h>

 

#define CODENUM 3

struct input_dev *btn_dev;      //input设备的结构体,这里定义了btn_dev

 

static keycode[] = {

       KEY_POWER,

       KEY_VOLUMEUP,

       KEY_VOLUMEDOWN

};

 

static int __init button_init(void)

{

    int error;

    //分配input设备

    btn_dev = input_allocate_device();

    if(!btn_dev)

    {

              printk(KERN_ERR "button: not enough memory\n");

        error = -ENOMEM;

              return error;

    }

    

    //把相应的按键给置上

btn_dev->evbit[0] = BIT_MASK(EV_KEY);

for(i = 0; i < CODENUM; i++)

           btn_dev->keybit[BIT_WORK(keycode[i])] |= BIT_MASK(keycode[i]);

    

    //注册input设备

    error = input_register_device(btn_dev);

    if(error)

    {

              printk(KERN_ERR "button: failed to register device\n");

return error;    

    }

       

    return 0;  

}

 

static void __exit button_exit(void)

{

    input_free_device(btn_dev);

}

 

module_init(button_init);

module_exit(button_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("eastmoon");

 

上面的驱动其实主要就是注册一个input设备,然后再注册要用到的按键的code而已,下面就是要用的应用程序来实现那个长按和短按的功能了。

 

#include <stdio.h>

#include <sys/ioctl.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/select.h>

#include <sys/time.h>

#include <linux/input.h>

#include <stdlib.h>

 

#define DEVICE "/dev/input/event0"   //这个根据自己的平台来的,不一定是event0的

 

int main(int argc, char *argv[])

{

    struct input_event btn;

    int fd, rev;

    unsigned short type;

    unsigned short code;

    int value;

       int longbt = 1;

       int delay = 0;  

 

    fd = open(DEVICE, O_RDWR);

    if(fd < 0)

    {

        printf("Open file %s failed!\n", DEVICE);

        return -1;

    }

 

       if(argv[2] == NULL)

       {

              Longbt = 0;     //命令行如果输入2个参数的话那么就默认的短按了

}

       else                

{

       longbt = atoi(argv[2]);

       if(longbt >= 10 || longbt < 0)

       {

              Printf(“Please input the longbt  0------9”);

              return 0;

}

delay = longbt *100000;           //longbt表示长按的时间,步进100ms。

}

 

btn.type = EV_KEY;                                               //表示按键按下了

btn.code = atoi(argv[1]);

       btn.value = 1; 

       rev = write(fd, &btn, sizeof(struct input_event));

       if(rev > 0)

{

              printf(“ok1\n”);

}

 

 

btn.type = EV_SYN;                                        //上报表示这个过程

btn.code = SYN_REPORT;

       btn.value = 0; 

       rev = write(fd, &btn, sizeof(struct input_event));

       if(rev > 0)

{

              printf(“ok3\n”);

}

 

       usleep(delay);               //按键按的时间

 

btn.type = EV_KEY;                                                             //表示按键抬起了

btn.code = atoi(argv[1]);

       btn.value = 0; 

       rev = write(fd, &btn, sizeof(struct input_event));

       if(rev > 0)

{

              printf(“ok2\n”);

}

 

btn.type = EV_SYN;                                               //上报表示这个过程好了

btn.code = SYN_REPORT;

       btn.value = 0; 

       rev = write(fd, &btn, sizeof(struct input_event));

       if(rev > 0)

{

              printf(“ok3\n”);

}

 

    close(fd);

 

    return 0;

}

 

至于怎么在android下编译一个应用程序的话,网上也讲得很多了,这里也还是讲讲吧。

首先在androidexternal/下新建个input_app目录,然后在下面建个.c文件就是上面这段代码,命名为vitual.c好了。然后建一个Android.mk文件

内容如下:

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_SRC_FILE := \

       virtual.c

 

LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)

LOCAL_MODULE_TAGS := eng

LOCAL_MODULE := virtual

 

include $(BUILD_EXECUTABLE)

 

然后在input_appmm后就可以得到一个vitualbin文件了,再把这个可执行文件拷贝到system/bin下就可以了。

然后就可以执行

virtual  116    //这个表示短按会锁屏或者解锁,其中116就是那个电源键的code了

virtual  116 6    //这个就可以表示长按了,然后会出来一个选择框,让你选择是否要关机了。

 

至此,关于android的按键功能就实现了,其短按、长按的功能也得以实现了。

 

抱歉!评论已关闭.