工程模式中用来测试按键响应的方法。通过列出测试按钮,按下某个键就设置该键显示变化即可。
(1)放置按钮的layout xml如下:
可根据实际情况来修改
(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;
}
验证结果如下:
========================================================================================================
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操作,实验不成功