Как подделать клавиши со стрелками для моей активности на Android
Я пытаюсь переопределить кнопки громкости, чтобы они действовали как клавиши со стрелками вверх / вниз (то есть они должны переместить фокус на все мои виды деятельности с возможностью фокусировки).
Для этого я отменяю свою деятельность dispatchKeyEvent()
Обратите внимание, что я также пытался onKeyDown()
но некоторая часть событий, связанных с клавишами регулировки громкости, все еще проходила через систему, мое устройство имеет звуковую обратную связь при изменении громкости. Я все еще мог слышать звуковой сигнал, но громкость на самом деле не менялась. Переключение на dispatchKeyEvent()
убрал звуковой сигнал из системы.
Вот мой ток dispatchKeyEvent()
метод:
@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);
}
способ, которым он настроен сейчас, использует разные методы для увеличения и уменьшения, но ни один из них не работает правильно, чтобы сместить фокус. Для клавиши "Вверх" я просто вызываю функцию dispatchKeyEvent() вручную, передавая ей клавишу d-pad up и то же действие, которое происходило с кнопкой регулировки громкости (поэтому, когда я нажимаю, она должна нажиматься, а когда я отпускаю, она должна отпускать). Мой вывод для кнопки вверх выглядит так:
press 24
press 19
release 24
release 19
для кнопки "вниз" я немного подправил ее, потому что подумал, может быть, тот факт, что нажатие на dpad происходило до того, как громкость отпала, сломал его, поэтому я создал работающий модуль, который будет одновременно нажимать и отпускать кнопку dpad
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);
}
};
и я задерживаю это на долю секунды, чтобы у меня была возможность выпустить том. Мой вывод для кнопки вниз выглядит так:
press 25
release 25
press 20
release 20
если я подключу USB-клавиатуру к своему устройству и нажму клавиши со стрелками, фокус перемещается правильно, и я вижу вывод вверх:
press 19
release 19
и для пуха:
press 20
release 20
Единственное отличие (насколько я могу судить) состоит в том, что фокус фактически перемещается правильно, когда я нажимаю стрелки на клавиатуре, и не перемещается вообще, когда я нажимаю кнопки громкости (которые подделывают кнопки со стрелками).
Я что-то пропускаю здесь? Может ли кто-нибудь помочь мне понять, как подделать клавиши со стрелками к моей деятельности, чтобы они на самом деле правильно перемещали фокус?
1 ответ
В конце концов я понял, что вам нужно использовать класс Instrumentation для отправки ключевых событий, и вы должны сделать это вне основного потока по некоторым причинам. Вот фрагменты, которые будут отправлять вниз и вверх:
new Thread(new Runnable() {
@Override
public void run() {
new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
}
}).start();
Если вы используете их вместо переопределенного dispatchKeyEvent из вопроса, он будет правильно перемещать фокус.