工程模式中用来测试按键响应的方法。通过列出测试按钮,按下某个键就设置该键显示变化即可。

(1)放置按钮的layout xml如下:

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

    <TextView
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        android:layout_alignParentTop="true"
        android:background="@android:color/darker_gray"
        android:gravity="center"
        android:text="@string/device_key_test"
        android:textAppearance="@android:style/TextAppearance.Large" />
    	
    <TableLayout 
    	android:id="@+id/table_layout"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:layout_below="@id/title">
    </TableLayout>    
</RelativeLayout>

 

可根据实际情况来修改

(2)新建key类

 

	public static class Key {
		Button button;
		int keyCode;
		String keyName;
		boolean keyPressed;

		public Key(int keyCode, String keyName, boolean keyPressed) {
			this.keyCode = keyCode;
			this.keyName = keyName;
			this.keyPressed = keyPressed;
		}
	}
并在activity的开始初始化数按键序列数组:

 

 

	private TableLayout mTableLayout;
	public final static String TAG = "DeviceKeyTest";
	private final static int COLUMN = 2;	//一行两个按键控件
	private static Key[] keyMap = {
		new Key(KeyEvent.KEYCODE_VOLUME_DOWN, "volume_down", false),
		new Key(KeyEvent.KEYCODE_VOLUME_UP, "volume_up", false),
		new Key(KeyEvent.KEYCODE_BACK, "back", false),
        	new Key(KeyEvent.KEYCODE_MENU, "menu", false),  
	};
(3)onCreate内容
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        for (int i = 0; i < keyMap.length; i++){
			keyMap[i].keyPressed = false;
		}
        
        mTableLayout = (TableLayout) findViewById(R.id.table_layout);
		mTableLayout.setStretchAllColumns(true);
		int totalCount = keyMap.length;
		int row = totalCount / COLUMN;
		int surplus = totalCount % COLUMN;
		Log.d(TAG, "row = " + row + " , surplus = " + surplus);
//在mTableLayout上放置测试按键序列		
		for (int i = 0; i < row; i++) {
 			TableRow newRow = new TableRow(this);
 			newRow.setWeightSum(COLUMN);
			for (int k = 0; k < COLUMN; k++) {
				final Button button = new Button(this);
				button.setTextAppearance(this,
						android.R.style.TextAppearance_Large);
				button.setText(keyMap[i * COLUMN + k].keyName);
				button.setSingleLine();
				button.setTextColor(Color.BLUE);
				button.setTextSize(21);
				button.setGravity(Gravity.CENTER);
				button.setLayoutParams(new LayoutParams(
						LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
				keyMap[i * COLUMN + k].button = button;
				newRow.addView(button, new TableRow.LayoutParams());
			}
			mTableLayout.addView(newRow, new TableLayout.LayoutParams());
		}
//不足一行的按键控件处理		
		if (surplus > 0) {
			TableRow surplusRow = new TableRow(this);
			for (int i = 0; i < surplus; i++) {
				final Button button = new Button(this);
				button.setTextAppearance(this,
						android.R.style.TextAppearance_Large);
				button.setText(keyMap[row * COLUMN + i].keyName);
				button.setSingleLine();
				button.setTextColor(Color.BLUE);
				button.setTextSize(21);
				button.setGravity(Gravity.CENTER);
				keyMap[row * COLUMN + i].button = button;
				surplusRow.addView(button, new TableRow.LayoutParams());
			}
			mTableLayout.addView(surplusRow, new TableLayout.LayoutParams());
		}
    }
(4)key的处理

 

    public boolean dispatchKeyEvent(KeyEvent event){
    	Log.d(TAG, "DeviceKeyTest: dispatchKeyEvent ");
    	boolean isPressed = false;
		if (event.getAction() == KeyEvent.ACTION_DOWN) {
			for (int i = 0; i < keyMap.length; i++) {
				if (keyMap[i].keyCode == event.getKeyCode()) {
					Log.d(TAG, "keyMap[i].keyName = " + keyMap[i].keyName);
					keyMap[i].keyPressed = true;
					keyMap[i].button.setVisibility(View.INVISIBLE);
					isPressed = true;
				}
			}

			if (isPressed) {
				boolean isAllPressed = true;
				for (int i = 0; i < keyMap.length; i++) {
					if (!keyMap[i].keyPressed) {
						isAllPressed = false;
						break;
					}
				}
				if (isAllPressed) {
					this.finish();
				}
				return true;
			}
		}
    	return false;
    }
    验证结果如下:

测试按键响应的activity && getevent和setevent 用adb模拟按键和TP_xml

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

      getevent&sendevent 是android系统下的一个工具,可以获取和模拟多种按键和触屏操作,期间获取和产生的产生的是raw event。关于event设备的获取,在 /proc/bus/input/devices 下面:$ adb shell cat /proc/bus/input/devices得到详细信息

(1)getevent首先在adb shell后执行getevent获取当前系统注册的input event信息。

getevent
add device 1: /dev/input/event4
  name:     "AVRCP"
add device 2: /dev/input/event0
  name:     "mtk-kpd"
add device 3: /dev/input/event3
  name:     "hwmdata"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 4: /dev/input/event2
  name:     "mtk-tpd"
add device 5: /dev/input/event1
  name:     "ACCDET"

       按下一次按键时显示:

/dev/input/event0: 0001 0074 00000001
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0001 0074 00000000
/dev/input/event0: 0000 0000 00000000

        其中/dev/input/event0是device的名字,0001是type,0074 是键码,最后一个根据type不同而不同,比如1按下0弹起。其中type如下定义:
#define EV_SYN          0x00  
#define EV_KEY          0x01  
#define EV_REL          0x02  
#define EV_ABS          0x03 

...................................

        键码的定义就是Linux的标准值,Input.h。

点击一次TP显示(不确定黑色重复部分为何会有):

/dev/input/event2: 0001 014a 00000001   //input_report_key(tpd->dev, BTN_TOUCH, 1); 
/dev/input/event2: 0003 0030 00000001   //input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 1);
/dev/input/event2: 0003 0035 000000af    //input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
/dev/input/event2: 0003 0036 0000008e   //input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
/dev/input/event2: 0003 0039 00000000   //input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, p);
/dev/input/event2: 0000 0002 00000000   //input_mt_sync(tpd->dev);
/dev/input/event2: 0000 0000 00000000   //结束
/dev/input/event2: 0003 0030 00000001
/dev/input/event2: 0003 0035 000000af
/dev/input/event2: 0003 0036 0000008e
/dev/input/event2: 0003 0039 00000000
/dev/input/event2: 0000 0002 00000000
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0001 014a 00000000     //input_report_key(tpd->dev, BTN_TOUCH, 0); 
/dev/input/event2: 0003 0030 00000000     //input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 1);
/dev/input/event2: 0003 0035 000000af      //input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
/dev/input/event2: 0003 0036 0000008e     //input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
/dev/input/event2: 0000 0002 00000000     //input_mt_sync(tpd->dev);
/dev/input/event2: 0000 0002 00000000
/dev/input/event2: 0000 0000 00000000    //结束

(2)setevent模拟发送一个input消息,命令格式:

adb shell sendevent [device] [type] [code] [value],发送时间、格式和上面的一样,需要注意的是在get中code显示的是十六进制,而send中需要用十进制。

        如果要模拟一次电源键,进adb shell后执行

sendevent /dev/input/event0 0001 0116 00000001
sendevent /dev/input/event0 0000 0000 00000000
sendevent /dev/input/event0 0001 0116 00000000
sendevent /dev/input/event0 0000 0000 00000000

       模拟一次TP操作,实验不成功