I'm trying to get a Sip'n'Puff device to work with an Android tablet. I have the S&P set to joystick mode. I've remapped the relevant joystick buttons to the down arrow key and the enter key by overriding dispatchKeyEvent in my activity, as such:
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_1) {
if(event.getAction() == KeyEvent.ACTION_DOWN) {
return dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
} else if(event.getAction() == KeyEvent.ACTION_UP) {
return dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN));
}
} else if(event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_2) {
if(event.getAction() == KeyEvent.ACTION_DOWN) {
return dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
} else if(event.getAction() == KeyEvent.ACTION_UP) {
return dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER));
}
}
return super.dispatchKeyEvent(event);
}
Now here's the issue. I've got my layout set up so that the user can visit every View in a loop by pressing the down arrow key. This works just fine using a physical keyboard. I've even remapped the tab key on the keyboard to down arrow and that works just fine.
With the S&P device, however, the key mapped to down arrow exhibits odd behavior. If I navigate through a ListView, the selection stops at the last item and focus won't move to the next View in the interface. I've confirmed that the KEYCODE_BUTTON_1 event is being caught and converted to DPAD_DOWN appropriately, it just doesn't do what it's supposed to do.
Given that remapping the tab key on the keyboard works correctly, could it be that the down arrow key simply does something different when a joystick is plugged in? Any ideas on what's happening here, and how I can fix it?
Edit: I've now tried the keyboard mode of the S&P device, which uses the enter and spacebar keys. I remapped space to down arrow, and ran into the exact same problem as above. So it doesn't seem to be a keyboard vs. joystick issue.
Edit edit: After some tinkering with postDelayed, it looks like dispatching a down arrow event doesn't actually cause navigation to occur. Or to be more precise, it only causes navigation to occur within the ListView. I guess remapping the tab key worked because it was being treated as tab while not in the ListView, and as down arrow while in the ListView. At least it's a lead?
Yet another edit: I think what's happening here is that navigation via a physical input device is handled outside of the Activity. I can navigate through the ListView because it's a View within the Activity, so it receives the DPAD_DOWN event from dispatchKeyEvent and reacts by moving the selection. However, it's not Views that normally handle navigation: it's some layer in the OS between the input device and the application. So the question now becomes how to get a hold of that navigation layer and override the key mappings there.