如何在android上欺骗我的活动的箭头键

如何在android上欺骗我的活动的箭头键,android,focus,keyevent,arrow-keys,spoof,Android,Focus,Keyevent,Arrow Keys,Spoof,我试图覆盖音量按钮,使其充当向上/向下箭头键(即,它们应将焦点移到我的所有活动可聚焦视图上。) 为此,我正在覆盖我的活动dispatchKeyEvent()方法注意,我也尝试了onKeyDown(),但我的部分音量键事件仍在通过系统,当您更改音量时,我的设备会有声音反馈。我仍然能听到嘟嘟声,但音量实际上没有改变。切换到dispatchKeyEvent()会消除系统发出的蜂鸣声 以下是我当前的dispatchKeyEvent()方法: @Override public boolean dispat

我试图覆盖音量按钮,使其充当向上/向下箭头键(即,它们应将焦点移到我的所有活动可聚焦视图上。)

为此,我正在覆盖我的活动
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向上键和音量按钮上发生的相同操作传递给它(因此,当我按下音量按钮时,它应按下,当我松开音量按钮时,它应松开),向上按钮的输出如下所示:

press 24
press 19
release 24
release 19
press 25
release 25
press 20
release 20
对于down按钮,我稍微调整了一下,因为我想可能是因为dpad按钮在音量释放之前就出现了,所以我做了一个runnable,可以同时按下和释放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 24
press 19
release 24
release 19
press 25
release 25
press 20
release 20
如果我将usb键盘插入设备并按箭头键,则焦点会正确移动,并且我会看到向上的输出:

press 19
release 19
至于down:

press 20
release 20
唯一的区别(据我所知)是,当我按下键盘上的箭头时,焦点实际上会正确移动,而当我按下音量按钮时,焦点根本不会移动(这模仿了箭头按钮)


我是不是忽略了什么?有谁能帮我找出如何将箭头键欺骗到我的活动中,以便它们能够正确地移动焦点吗?

我最终发现,您需要使用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将正确地移动焦点