28

ドロイドのキー押下をプログラムでシミュレートするにはどうすればよいですか?手動のキー押下を模倣したいと思います(誰かがキーを押しているようにドロイドに表示されますが、プログラムで実行されています)。

を含む解決策がありますがIWindowManager、それは新しいSDKではもはやオプションではありません。

4

4 に答える 4

42

インストルメンテーションを使用できます。つまり、アクティビティの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();

...しかし、これがあなたが求めているものかどうかはわかりません

于 2012-01-02T01:15:13.373 に答える
14

イベントを使用するビューがある場合は、BaseInputConnectionクラスとそのsendKeyEventメソッドを使用できます。

これを使用するには、KeyEventを受け取るターゲットビュー(EditTextなど)を指定する必要があります。例えば:

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

この結果は、ユーザーが実際に#キーを押したようなものです(編集テキストをフォーカスした状態で)。

于 2017-02-01T17:38:32.893 に答える
1

私の意見では、インストルメンテーションを使用すると意図したとおりに機能しません。editTextにフォーカスがあると、ソフトキーボードがポップすることがあります。

私のプロジェクトでは、通常のキーボードのように機能するテンキーの断片があります。これが、目的のソリューションを実現するための私の方法です。

私はAndroid7+を搭載した3つのデバイスでこのソリューションをテストしました:

キーボードフラグメント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に移動します。

これは少し大まかな解決策ですが、問題なく機能します。

于 2021-07-08T09:39:54.920 に答える
0

UI Automatorテストを実行している場合、デバイスのAndroidバージョンに応じて使用できる2つの手法があります。

API 21+

API 18以降のみを対象とする場合は、シェルを使用するだけです。

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もサポートしている場合、シェルは使用できないため使用できません。また、システム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);
于 2021-02-28T03:30:49.737 に答える