好的,我想我已经为您找到了可行的解决方案。原来我做错了一些事情。一个dispatchKeyEvent()
比onKeyDown()
因为它阻止按下音量按钮进入系统要好(在我的设备上,它们会发出哔哔声,但没有音量变化)。而且事实证明,您需要使用Instrumentation类来发送欺骗 KeyEvents 而不是手动调用dispatchKeyEvent()
. Instrumentation 类也不会从主线程进行方法调用,因此您必须将调用包装在它们自己的线程中。
我还了解了为什么您设备上的某些按钮会发送两个关键事件 117 和 71。这些与shift+匹配。[出于我们的目的,我们可以忽略 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);
}
这将允许您控制演示者设备上的 3 个按钮(Vol Up、Vol Down 和 Left 可编程按钮),通过将您的代码片段放在 if 语句的适当分支中,您可以使这 3 个按钮中的任何一个执行无论你想要什么。
我创建了一个测试项目来实现这一点,如果您想查看整个内容,可以在此处下载压缩的项目文件夹。在这个测试项目中,我进行了设置,以便 vol up/down 将用作 d-pad up/down,这将允许您将焦点移动到活动中的不同视图。
这是您可以放在 if 语句的一个分支中以欺骗 d-pad 箭头按钮的代码:
new Thread(new Runnable() {
@Override
public void run() {
new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
}
}).start();
you can replace the KeyEvent.KEYCODE_DPAD_DOWN
with any other key event that you want for instance KeyEvent.KEYCODE_DPAD_UP
or KeyEvent.KEYCODE_DPAD_CENTER
the latter of which would act as a select button which will send a click event to the button that currently has focus.