zoukankan      html  css  js  c++  java
  • 和菜鸟一起学android4.0.3源码之按键驱动短长按功能

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

           上周由于其他部门需要用我们的芯片,得模拟个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的按键功能就实现了,其短按、长按的功能也得以实现了。

     

  • 相关阅读:
    自省改过
    c语言学习教程1之预定义代码
    tqdm进度条管理
    React-i18next切换中英文
    React怎样实现点击其他地方隐藏弹出的菜单
    遍历对象再取值,获得新值
    Web 用户体验设计提升指南
    antd vue form
    echarts 内容显示值在图中显示,不显示交互效果,只是静态图
    element-ui中el-table根据浏览器的缩放自适应宽度
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300058.html
Copyright © 2011-2022 走看看