Android中添加自定义按键 ---- 非标准做法

原创 2012年03月29日 16:43:54

这里我来介绍一下怎么在Android中添加自定义按键,首先要打通kernel中的驱动,然后是Android层,我这里介绍一种不是很标准的方法,项目需要。

首先是Linux中,我这里只是把已有的search 按钮替换成我们的用户按钮,并提供长按和短按功能。

修改板级文件,我这边使用的事Freescale imx53的开发板

kernel/arch/arm/mach-mx5/mx53_smd.c 

定义按键与哪个GPIO连接

//+++++add our own user button
#define MX53_MDK_KEY_USER			(1*32 + 23)	/* GPIO_2_23 */
#define MX53_MDK_KEY_SEARCH			(1*32 + 23)	/* GPIO_2_23 */

然后定义这个按键的信息

static struct gpio_keys_button smd_buttons[] = {
#ifdef CONFIG_MACH_MX53_MIPAD
	GPIO_BUTTON(MX53_MIPAD_KEY_VOL_UP, KEY_VOLUMEUP, 1, "volume-up", 0),
	GPIO_BUTTON(MX53_MIPAD_KEY_VOL_DOWN, KEY_VOLUMEDOWN, 1, "volume-down", 0),
#elif defined(CONFIG_MACH_MX53_MDK)
	//+++++modify for user button by Jay
//	GPIO_BUTTON(MX53_MDK_KEY_SEARCH, KEY_SEARCH, 1, "search", 0),
	GPIO_BUTTON(MX53_MDK_KEY_USER, KEY_F1, 1, "user", 0),
	GPIO_BUTTON(MX53_MDK_KEY_HOME, KEY_HOME, 1, "home", 0),
	GPIO_BUTTON(MX53_MDK_KEY_BACK, KEY_BACK, 1, "back", 0),
	GPIO_BUTTON(MX53_MDK_KEY_MENU, KEY_MENU, 1, "menu", 0),
	GPIO_BUTTON(MX53_SMD_KEY_VOL_UP, KEY_VOLUMEUP, 1, "volume-up", 0),
	GPIO_BUTTON(MX53_SMD_KEY_VOL_DOWN, KEY_VOLUMEDOWN, 1, "volume-down", 0),
#else
	GPIO_BUTTON(MX53_SMD_KEY_VOL_UP, KEY_VOLUMEUP, 1, "volume-up", 0),
	GPIO_BUTTON(MX53_SMD_KEY_VOL_DOWN, KEY_VOLUMEDOWN, 1, "volume-down", 0),
#endif
};

这里我把键值定义为KEY_F1

然后我们在按键驱动中添加新的按键和功能,

/kernel/drivers/input/keyboard/gpio_keys.c

static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
	struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	unsigned int type = button->type ?: EV_KEY;
	int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;

	//+++add by Jay
	struct device *dev = &bdata->input->dev;
	char event_string[20];
	char *envp[] = { event_string, NULL };
	//----

#ifdef CONFIG_MACH_MX53_MIPAD
	input_event(input, type, button->code, !state);
#else
	//++++++add user button by Jay
	if(button->code == KEY_F1) {
		if(state) {
			startKeyTime = (jiffies*1000)/HZ;
			user_button_state = 1;
			user_thread = kthread_run(user_thread_handler,
					dev, "user-button");
		} else {
			user_button_state = 0;
			if((jiffies*1000)/HZ - startKeyTime < 1500)
			{
				sprintf(event_string, "EVENT=shortpress");
				kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
				printk("short press\r\n");
			}
		}
	}
	//-----
	else
		input_event(input, type, button->code, !!state);
#endif
	input_sync(input);
}


首先在按键中断到来的时候我们要判断出是我们定义的user button,当按下的时候产生一个下降沿中断,按下的时候state应该为1,先记录按下时的时间,然后开启一个线程,看下线程中做了什么

//++++add by Jay
#include <linux/kthread.h>
static int startKeyTime = 0;
static int user_button_state = 0;
static struct task_struct *user_thread;

static int user_thread_handler(void *arg)
{
	struct device *dev = arg;

	while(user_button_state == 1)
	{
		char event_string[20];
		char *envp[] = { event_string, NULL };

		msleep(100);
		if(((jiffies*1000)/HZ) - startKeyTime > 1500)
		{
			sprintf(event_string, "EVENT=longpress");
			kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
			printk(KERN_INFO "user button long press.\n");
			break;
		}
	}
	return 0;
}
//-----

在线程中我们不断判断state的值,如果一直按下,就判断按下了多久,当达到我们定义的长按时间的话,就会像上层发送一个长按的uevent事件,否则返回。

在按键抬起的时候也会产生中断,这样的话在else语句中会做判断,然后向user space发送一个uevent事件。

-------------------------------------------------

接下来我们看下在android中我们如何捕获

我们使用ueventObserver的方式去捕获uevent事件,详细的不多说了,可以参考我之前的博文有介绍uevent在android中的用法,直接贴代码,本人对java不是很熟悉,简单的代码就不来卖弄了,呵呵。

我们把代码加载ActivityManagerService.java中

    //+++++add for our uevent by Jay
    private Handler UeventHandler=new Handler()
    {
	    @Override
	    public void handleMessage(Message msg)
	    {
		    super.handleMessage(msg);
		    if(msg.what==0)
		    	Toast.makeText(mContext,"short press!" ,Toast.LENGTH_SHORT).show();
		    if(msg.what==1)
			Toast.makeText(mContext,"long press!" ,Toast.LENGTH_SHORT).show();
	    }
    };
    private UEventObserver mShortUEventObserver = new UEventObserver()
    {
	    @Override
	    public void onUEvent(UEventObserver.UEvent event)
	    {
		    UeventHandler.sendEmptyMessage(0);
	    }
    };

    private UEventObserver mLongUEventObserver = new UEventObserver()
    {
	    @Override
	    public void onUEvent(UEventObserver.UEvent event)
	    {
		    UeventHandler.sendEmptyMessage(1);
	    }
    };
    //------end add
    final void finishBooting() {
	//+++++add by Jay for user button
	mShortUEventObserver.startObserving("EVENT=shortpress");
	mLongUEventObserver.startObserving("EVENT=longpress");
	//-------
        IntentFilter pkgFilter = new IntentFilter();
        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
        pkgFilter.addDataScheme("package");
        mContext.registerReceiver(new BroadcastReceiver() {

当bootFinish的时候我们就开始侦测这2个uevent时候被发生,然后用toast来显示。

最后重新编译,烧到我们的开发板中,当短按的时候会有信息吐出来,长按超过1.5s也会有信息吐出来。


分享工作经验,结束。

=========================================================

mail & MSN :zhangjie201412@live.com

=========================================================




Android下添加新的自定义键值和按键处理流程

Android下添加新的自定义键值和按键处理流程     说出来不怕大家笑话,我写这篇博客的原因在于前几天去一个小公司面试Android系统工程师,然后在面试的时候对方的技术总监问了我一个问题,请你...
  • tkwxty
  • tkwxty
  • 2015年01月31日 09:37
  • 18155

Android下添加新的自定义键值和按键处理流程

Android下添加新的自定义键值和按键处理流程 2015-01-31 09:37 5590人阅读 评论(0) 收藏 举报 本文章已收录于: 版权声明:本文为博主原创文章,未经博主允...
  • u012719256
  • u012719256
  • 2016年08月19日 17:08
  • 2931

android 添加新的键值,自定义按键

在android中,上层可使用的键值默认情况下是92个,从0-91;一般情况下,这些键值是够用的,但是如果想扩充的话,还是需要添加新的键值的,那么如何将一个新的键值从驱动的设置映射到上层,使应用可以对...
  • mr_raptor
  • mr_raptor
  • 2014年06月13日 10:22
  • 8916

android遥控器新增自定义的键值+用遥控器按键实现软键盘字符键的切换(amlogice平台) --- (一)

最近的项目客户有个需求,遥控器上要增加两个按键,分别是系统软键盘的DEL键和字符切换键(也就是左下角那个按键)。任务相对来说比较简单,所以安排给我这个新手做,废话不多说,直接上正题,有不对的地方,欢迎...
  • Darren_Mr
  • Darren_Mr
  • 2016年12月15日 19:48
  • 1450

linux设置非标准波特率200000bit/s

#include      /*标准输入输出定义*/ #include     /*标准函数库定义*/ #include     /*Unix 标准函数定义*/ #include #i...
  • w_ww_w
  • w_ww_w
  • 2014年05月14日 11:47
  • 3186

RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键

瑞芯微平台 SDK:Android4.4 好久没写博客了,最近工作中需要在SDK中添加一个新的遥控器支持,由于自己对java代码比较头大,过程也是一波三折,整个流程其实分析下来并不难,这里做个简单...
  • coding__madman
  • coding__madman
  • 2016年10月23日 20:26
  • 3549

linux下非标准波特率的设置和使用

转载于 http://blog.chinaunix.net/uid-9543173-id-1988980.html
  • w_ww_w
  • w_ww_w
  • 2014年05月14日 13:35
  • 1283

android系统定制化添加按键驱动步骤

修改按键做法比较简单,只要每个key的按键功能正常的话,只需更换驱动事件对应的key值,故我们先检查整个流程是否打通,打通的话就是改两端而已,要么在onKeyDown()或onkeyUp()上加功能而...
  • mmmccc000
  • mmmccc000
  • 2015年11月12日 12:31
  • 1017

Android6.0 按键流程(一)读取设备事件

之前我们整理过一篇按键流程,但是不是太详细有的细节的地方有遗漏,今天在Android6.0上重新总结下,先从读取按键值作为第一篇。 一、初始化 InputManagerService在System...
  • kc58236582
  • kc58236582
  • 2016年01月29日 16:19
  • 4554

android 增加一个新的硬按键

Android已经定义了比较丰富、完整的标准按键。在一般情况下,不需要为Android系统增加按键,只需要根据kl配置按键即可。在系统中有比较奇特按键的时候,需要更改Android系统的框架层来更改按...
  • jianguo_liao19840726
  • jianguo_liao19840726
  • 2014年09月29日 14:38
  • 909
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android中添加自定义按键 ---- 非标准做法
举报原因:
原因补充:

(最多只允许输入30个字)