ドロイドのキー押下をプログラムでシミュレートするにはどうすればよいですか?手動のキー押下を模倣したいと思います(誰かがキーを押しているようにドロイドに表示されますが、プログラムで実行されています)。
を含む解決策がありますがIWindowManager
、それは新しいSDKではもはやオプションではありません。
インストルメンテーションを使用できます。つまり、アクティビティの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();
...しかし、これがあなたが求めているものかどうかはわかりません
イベントを使用するビューがある場合は、BaseInputConnectionクラスとそのsendKeyEventメソッドを使用できます。
これを使用するには、KeyEventを受け取るターゲットビュー(EditTextなど)を指定する必要があります。例えば:
EditText editText;
BaseInputConnection inputConnection = new BaseInputConnection(editText, true);
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POUND));
この結果は、ユーザーが実際に#キーを押したようなものです(編集テキストをフォーカスした状態で)。
私の意見では、インストルメンテーションを使用すると意図したとおりに機能しません。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に移動します。
これは少し大まかな解決策ですが、問題なく機能します。
UI Automatorテストを実行している場合、デバイスのAndroidバージョンに応じて使用できる2つの手法があります。
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-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);