如何在Droid上通过编程模拟按键操作?我想模拟手动按键操作(类似于某人在按键,但实际上是通过程序完成的)。
尽管涉及到IWindowManager
的解决方案,在新SDK中已不再是可行选项。
你可以使用仪器,比如在你的Activity的onCreate方法中调用以下代码将会导致菜单被多次打开和关闭:
new Thread(new Runnable() {
@Override
public void run() {
try {
Instrumentation inst = new Instrumentation();
for ( int i = 0; i < 10; ++i ) {
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
Thread.sleep(2000);
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
Thread.sleep(2000);
}
}
catch(InterruptedException e){
}
}
}).start();
... 但我不确定这是否是您想要的。
EditText editText;
BaseInputConnection inputConnection = new BaseInputConnection(editText, true);
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POUND));
这样做的结果就像用户实际上按下了#键(同时保持编辑文本聚焦)。
KeyEvent.ACTION_UP
。我猜这样做是合乎逻辑的。 - Peter在我看来,使用仪器并不能像预期的那样起作用,当editText被聚焦时,它有时会导致软键盘弹出。
在我的项目中,我有一个数字键盘片段,应该像普通键盘一样工作,这是我实现所需解决方案的方式:
我在三个安卓7+设备上测试了这个解决方案:
键盘片段onClick():
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button0:
simulateKeyPress(KeyEvent.KEYCODE_0);
break;
case R.id.button1:
simulateKeyPress(KeyEvent.KEYCODE_1);
break;
case R.id.button2:
simulateKeyPress(KeyEvent.KEYCODE_2);
break;
case R.id.button3:
simulateKeyPress(KeyEvent.KEYCODE_3);
break;
case R.id.button4:
simulateKeyPress(KeyEvent.KEYCODE_4);
break;
case R.id.button5:
simulateKeyPress(KeyEvent.KEYCODE_5);
break;
case R.id.button6:
simulateKeyPress(KeyEvent.KEYCODE_6);
break;
case R.id.button7:
simulateKeyPress(KeyEvent.KEYCODE_7);
break;
case R.id.button8:
simulateKeyPress(KeyEvent.KEYCODE_8);
break;
case R.id.button9:
simulateKeyPress(KeyEvent.KEYCODE_9);
break;
}
}
public void simulateKeyPress(int key){
Activity a = (Activity) getContext();
a.getWindow().getDecorView().getRootView();
BaseInputConnection inputConnection = new BaseInputConnection(a.getWindow().getDecorView().getRootView(),
true);
KeyEvent downEvent = new KeyEvent(KeyEvent.ACTION_DOWN, key);
KeyEvent upEvent = new KeyEvent(KeyEvent.ACTION_UP, key);
inputConnection.sendKeyEvent(downEvent);
inputConnection.sendKeyEvent(upEvent);
}
我将事件发送到活动的根视图,然后再传递到所需的聚焦editText。
这是一种简单粗暴的解决方案,但效果很好。
如果您正在运行UI Automator测试,则可以根据设备的Android版本使用两种技术:
如果您只针对API 18或更高版本进行目标设置,则可以直接使用shell:
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
device.executeShellCommand("input text 1234"); // Type '1234'
device.executeShellCommand("input keyevent 66"); // Press the Enter key
如果您还支持API 18-19,则不能使用shell,因为它不可用,如果您正在与不属于自己的应用程序交互,例如系统UI,则无法使用仪器键注入。而是使用UiAutomation.injectInputEvent()。
获取UiAutomation
的实例并将其存储在某个地方:
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
然后定义一些辅助方法:
private void sendKey(int keyCode) {
sendKeyEvent(keyCode, KeyEvent.ACTION_DOWN);
sendKeyEvent(keyCode, KeyEvent.ACTION_UP);
}
private void sendKeyEvent(int keyCode, int action) {
long downTime = SystemClock.uptimeMillis();
KeyEvent event = new KeyEvent(
downTime,
downTime,
action,
keyCode,
0,
0,
KeyCharacterMap.VIRTUAL_KEYBOARD,
0,
KeyEvent.FLAG_FROM_SYSTEM,
InputDevice.SOURCE_KEYBOARD
);
uiAutomation.injectInputEvent(event, true);
}
然后像这样使用:
sendKey(KeyEvent.KEYCODE_1);
sendKey(KeyEvent.KEYCODE_2);
sendKey(KeyEvent.KEYCODE_3);
sendKey(KeyEvent.KEYCODE_4);
sendKey(KeyEvent.KEYCODE_ENTER);
pressEnter()
、pressHome()
等等。 - Ishaan Kumarinput keyevent 66
和pressEnter()
哪个更快?"66"是回车键的代码。 - Ishaan Kumar