わかりました。私はあなたのために実用的な解決策を持っていると思います。いくつか間違っていたことがわかりました。1つdispatchKeyEvent()
は、音量ボタンの押下がシステムに到達するのを停止するためよりも優れonKeyDown()
ています(私のデバイスでは、ビープ音が鳴りましたが、音量は変化しませんでした)。また、手動でを呼び出す代わりに、 Instrumentationクラスを使用してなりすましのKeyEventsを送信する必要があることもわかりましdispatchKeyEvent()
た。Instrumentationクラスはメインスレッドからもメソッド呼び出しを行わないため、呼び出しを独自のスレッドでラップする必要があります。
また、デバイスの一部のボタンが2つのキーイベント117と71を送信している理由も学びました。これらはshift+まで一致し[ます。私たちの目的では、シフトプレスを無視し、を使用し[てアクションを実行できます。
これは、私のために機能しているように見えるオーバーライドされたdispatchKeyEvent()メソッドです。
@Override
public boolean dispatchKeyEvent(KeyEvent ke){
int keyCode = ke.getKeyCode();
if(ke.getAction() == KeyEvent.ACTION_DOWN){
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
/**************************************
* What ever code snippet you put
* here will run whenever you press the
* volume down button on your presenter
* device
**************************************/
return true;
}else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
/**************************************
* What ever code snippet you put
* here will run whenever you press the
* volume up button on your presenter
* device
**************************************/
return true;
}else if (keyCode == 30){
/**************************************
* What ever code snippet you put
* here will run whenever you press the
* left programmable button on your
* presenter device
**************************************/
return true;
}
else if (keyCode == 59){
/**************************************
* This was an attempt to get it to ignore
* the shift keypress coming from the
* left/right arrow keys on the devices
* ignoring that would in theory make
* those keys function as up/down focus
* movers. Didn't seem to work though.
* you could probably remove this branch
* of the if statement if you want.
* However since those buttons do send
* key events to the device it should
* should still be possible override these
* buttons somehow.
**************************************/
return true;
}
}else if(ke.getAction() == KeyEvent.ACTION_UP){
/**************************************
* This section will catche the "release"
* events from all of the keys we are using
* and tell the system that we've handled
* them. So that the system will not pass
* the events along to anything else.
**************************************/
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
/**************************************
* If you had any reason / desire to
* you could put a code snipet here and it
* would be run when you let go after
* pressing the volume down button on your
* presenter device.
**************************************/
return true;
}else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
return true;
}else if (keyCode == 59){
return true;
}else if (keyCode == 30) {
return true;
}
}
/**************************************
* The following line is needed so that
* the system will treat any key events
* that we aren't interested in normally.
* i.e. the back button on the tablet, by
* by calling super.dispatchKeyEvent(), we
* ensure that the back button still behaves
* like normal.
**************************************/
return super.dispatchKeyEvent(ke);
}
これにより、コードスニペットをifステートメントの適切なブランチに配置することで、プレゼンターデバイスの3つのボタン(音量大、音量小、左のプログラム可能なボタン)を制御できるようになります。これらの3つのボタンのいずれかを実行できます。あなたが望むものなら、なんでも。
これを実装するテストプロジェクトを作成しました。全体を確認したい場合は、ここからzip形式のプロジェクトフォルダーをダウンロードできます。このテストプロジェクトでは、vol up/downがd-padup/ downとして機能するように設定しました。これにより、アクティビティ内のさまざまなビューにフォーカスを移動できます。
十字キーの矢印ボタンをスプーフィングするためにifステートメントのブランチの1つに入れることができるコードは次のとおりです。
new Thread(new Runnable() {
@Override
public void run() {
new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
}
}).start();
たとえば、KeyEvent.KEYCODE_DPAD_DOWN
を必要な他のキーイベントに置き換えることができます。後者は、現在フォーカスがあるボタンにクリックイベントを送信する選択ボタンとして機能します。KeyEvent.KEYCODE_DPAD_UP
KeyEvent.KEYCODE_DPAD_CENTER