[置顶] android按键功能的拓展

按键事件,大概由3部分,

1.底层调用input.h中的键值(如果新定义按键可以自行加入键值,反正在.kl文件做个映射就行)

2.一个映射到framework的映射文件在system/usr/keylayout/*.kl文件

3.具体按键功能的事件和功能拓展在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java




项目中的情况,正常情况下在线控耳机上MUSIC的情况下是MEDIA_NEXT(下一首)和MEDIA_PREVIOUS(上一首),这个本身android是支持的,现在需要支持在电话状态下是音量加减的功能.

1.如果遇到硬件采集电压不稳,软件上的解决办法。底层按键驱动采集ADC电压不稳的解决办法,采集是使用定时器轮询的方式

 解决办法:

                    a.加大定时器的采集密度,并做状态统计,在同一状态下采集5次,就上报按键//加大采集密度,必然导致消耗cpu,所以在没有按键事件的时候保持原来的采集密度,只有当满足按键条件的时候再加大采集频率

  static void  lradc1_data_function(unsigned long data)

{    

volatile unsigned int  reg_val;

static int key_pressed = -1, count = 0;  

 int delay = HZ/40; //默认在为HZ/40采集,程序后面reg_val>0x34时,按键时为HZ/4,降低了采集频率,节省cpu资源,当有按键按下时采集HZ/40
+    if (reg_val >=0 && reg_val < 0x5 )
+    {
+            // hook key
+            if (key_pressed == 0)      //按物理键是按了0,如果相等的话,就计数加一
+                count++;
+            else {
+                key_pressed = 0;  //如果按物理键0,但不相等(为了防止误触的可能)强制赋值0 ,并且计数清0
+                count = 0;
+            }
+
+            if (count > 5)
+            {
+                            sw_pressed[0] = 1;
+                 input_report_key(sun4ikbd_dev, HOOK_KEY, 1);
+                 input_sync(sun4ikbd_dev);
+                 printk("[lkj] input key sw1 down \n");
+                 count = 0;
+            }
+
+
+
+    }
+    else if( reg_val >= 0x6 && reg_val <= 0xb  )
+    {
+        // sw2
+            if (key_pressed == 1)
+                count++;
+            else {
+                key_pressed = 1;
+                count = 0;
+            }
+
+            if (count > 5)
+            {
+                            sw_pressed[1] = 1;
+                 input_report_key(sun4ikbd_dev, SW2_KEY, 1);
+                 input_sync(sun4ikbd_dev);
+                 printk("[lkj] input key sw2 down \n");
+                 count = 0;
+            }
+
+    }

 else if ( reg_val >= 0xf && reg_val < 0x1f )
+    {
+        // sw3
+             if (key_pressed == 2)
+                count++;
+            else {
+                key_pressed = 2;
+                count = 0;
+            }
+
+            if (count > 5)
+            {
+                            sw_pressed[2] = 1;
+                 input_report_key(sun4ikbd_dev, SW3_KEY, 1);
+                 input_sync(sun4ikbd_dev);
+                 printk("[lkj] input key sw3 down \n");
+                 count = 0;
+            }
+
+   }
+    else if ( reg_val >= 0x34) {
+        key_pressed = -1;
+        count = 0;
+               if (sw_pressed[0])
+               {
+                       sw_pressed[0] = 0;
+                        input_report_key(sun4ikbd_dev, HOOK_KEY, 0);
+                        input_sync(sun4ikbd_dev);
+                        printk("[lkj] input key sw1 up \n");
+               }
+               if (sw_pressed[1])
+               {
+                       sw_pressed[1] = 0;
+                        input_report_key(sun4ikbd_dev, SW2_KEY, 0);
+                        input_sync(sun4ikbd_dev);
+                        printk("[lkj] input key sw2 up \n");
+               }
+               if (sw_pressed[2])
+               {
+                       sw_pressed[2] = 0;
+                        input_report_key(sun4ikbd_dev, SW3_KEY, 0);
+                        input_sync(sun4ikbd_dev);
+                        printk("[lkj] input key sw3 up \n");
+               }
+        delay = HZ/4;
}
 mod_timer(&mic_data->timer, jiffies +  delay);
}

                 



2.写个映射就可以

3.找到MEDIA_NEXT和MEDIA_PREVIOUS,区分2个状态,music和in_call,

diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 8badbdd..1f4b785 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2982,11 +2982,32 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                         }
                     }
                 }
+            case KeyEvent.KEYCODE_MEDIA_NEXT:
+            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+               if (down) {
+            AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);//实例化这个audioManager,并用文件中的mContext
+
+                       ITelephony telephonyService = getTelephonyService();
+                       try {
+                               if (telephonyService.isOffhook()) {
+                                       Log.d(TAG, "++++++++---+++++telephonyService.isOffhook="+telephonyService.isOffhook());//isOffhook ==true 为通话状态下
+                    audioManager.adjustSuggestedStreamVolume(
+                            keyCode == KeyEvent.KEYCODE_MEDIA_NEXT ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER,
+                            AudioManager.STREAM_RING,
+                            AudioManager.FLAG_SHOW_UI);//调用AudioManager在in_call情况下调整音量并出现音量状态栏
+
+                               break;
+                               }//如果不在in_call状态下,就走下面源代码的线路
+                       } catch (RemoteException ex) {
+                            Log.w(TAG, "ITelephony threw RemoteException", ex);
+                        }
+               }
             case KeyEvent.KEYCODE_HEADSETHOOK:
             case KeyEvent.KEYCODE_MUTE:
             case KeyEvent.KEYCODE_MEDIA_STOP:
-            case KeyEvent.KEYCODE_MEDIA_NEXT:
-            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
             case KeyEvent.KEYCODE_MEDIA_REWIND:
             case KeyEvent.KEYCODE_MEDIA_RECORD:
             case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
(END)




你可能感兴趣的:(android,UI,service,Class,电话)