I am trying to override the volume buttons to act as Up/Down arrow keys (i.e. they should move focus around on all of my activities focus-able Views.)
To do so I am overriding my activities dispatchKeyEvent()
method note that I also tried onKeyDown()
but some portion of my volume key events was still going thru to the system, my device has audible feedback when you change the volume. I could still hear the beep but the volume was not actually being changed. Switching to dispatchKeyEvent()
took away the beep coming from the system.
Here is my current dispatchKeyEvent()
method:
@Override
public boolean dispatchKeyEvent(KeyEvent ke){
int keyCode = ke.getKeyCode();
if(ke.getAction() == KeyEvent.ACTION_DOWN){
print("press " + keyCode);
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
mTxt.postDelayed(pressDown, 600);
return true;
}else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP);
dispatchKeyEvent(key);
return true;
}
}else if(ke.getAction() == KeyEvent.ACTION_UP){
print("release " + keyCode);
if(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
/*KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN);
dispatchKeyEvent(keyUp);*/
return true;
}else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_UP);
dispatchKeyEvent(keyUp);
return true;
}
}
return super.dispatchKeyEvent(ke);
}
the way it is set up now it is using different techniques for up and down, but neither are working correctly to shift focus. For the Up key I simply make a manual call to dispatchKeyEvent() passing it the d-pad up key and the same action that took place on the volume button (so when I press it should press, and when I release it should release) My output for the up button looks like this:
press 24
press 19
release 24
release 19
for the down button I tweaked it slightly because I thought maybe the fact that the dpad press was happening before the volume release was breaking it, so I made a runnable that will both press and release the dpad button
pressDown = new Runnable(){
@Override
public void run(){
KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN);
dispatchKeyEvent(key);
KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN);
dispatchKeyEvent(keyUp);
}
};
and I delay that by part of a second so that I have a chance to release the volume. My output for the down button looks like this:
press 25
release 25
press 20
release 20
if I plug in a usb keyboard to my device and press the arrow keys the focus moves correctly and I see the output for up:
press 19
release 19
and for down:
press 20
release 20
The only difference (so far as I can tell) is that the focus actually moves correctly when I press the arrows on my keyboard, and doesn't move at all when I press the volume buttons (which spoof the arrow buttons)
Am I overlooking something here? Can anyone help me to figure out how to spoof arrow keys to my activity so that they will actually move focus correctly?