Android模拟按键

时间:2012-01-02 00:16:19

标签: java android key keypress simulate

如何以编程方式模拟Droid上的按键?我想模仿一个手动按键(出现在机器人上,有人按下一个键,但它是以编程方式完成的)。

有一些涉及IWindowManager的解决方案,但在新的SDK中不再是一个选项。

5 个答案:

答案 0 :(得分:38)

您可以使用检测,即从您的活动的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();

......但我不确定这是不是你的目标

答案 1 :(得分:6)

如果您有想要使用该活动的视图,则可以使用BaseInputConnection类及其sendKeyEvent方法。

要使用它,您需要指定将接收KeyEvent的目标视图(例如EditText)。例如:

EditText editText;
BaseInputConnection inputConnection = new BaseInputConnection(editText, true);
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POUND));

这样的结果就像用户实际按#键(同时重点编辑文本)。

答案 2 :(得分:0)

您也可以使用input text,即:

从计算机通过adb

adb shell input text 'example\\@email.com'  

来自shell

input text 'example\\@email.com'  

答案 3 :(得分:0)

如果您正在运行 UI Automator 测试,则可以根据设备的 Android 版本使用两种技术:

API 21+

如果您只针对 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+

如果您还支持 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);

答案 4 :(得分:0)

在我看来,使用仪器不能按预期工作,当 editText 聚焦时,它有时会导致软键盘弹出。

在我的项目中,我有一个数字键盘片段,它应该像普通键盘一样工作,这是我实现所需解决方案的方式:

我在 3 台装有 android 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);
}

通过这种方式,我将事件发送到活动的根视图,然后它会转到所需的焦点编辑文本。

这是一个有点粗糙的解决方案,但工作正常。