1

I am making an app, a game, and I want the player to be able to use the back button for jumping(for single-touch devices). My target platform is 2.1(API level 7).

I've tried both onKeyDown() and onBackPressed(), but they are only called when the back button is RELEASED, not when it is pressed down.

1) Is this normal?

2) How can I make it so it registers the press when the button is pressed?

EDIT: I'd also like to add that it works correctly using a keyboard(onKeyDown is called when a key is pressed down).

Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
Jonathan
  • 489
  • 1
  • 7
  • 18

1 Answers1

1

Update: I got curious about this. Take a look at the android.view.View source code: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/view/View.java

a typical example would be handling the BACK key to update the application's UI instead of allowing the IME to see it and close itself.

code:

/**
 * Handle a key event before it is processed by any input method
 * associated with the view hierarchy.  This can be used to intercept
 * key events in special situations before the IME consumes them; a
 * typical example would be handling the BACK key to update the application's
 * UI instead of allowing the IME to see it and close itself.
 *
 * @param keyCode The value in event.getKeyCode().
 * @param event Description of the key event.
 * @return If you handled the event, return true. If you want to allow the
 *         event to be handled by the next receiver, return false.
 */
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    return false;
}

Using dispatchKeyEvent:

@Override
public boolean dispatchKeyEvent (KeyEvent event) {
    Log.d("**dispatchKeyEvent**", Integer.toString(event.getAction()));
    Log.d("**dispatchKeyEvent**", Integer.toString(event.getKeyCode()));
    if (event.getAction()==KeyEvent.ACTION_DOWN && event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
        Toast.makeText(this, "Back button pressed", Toast.LENGTH_LONG).show();
        return true;
    }
    return false;
}

Logs the two events independently even for the back key. The only key that did not log was KEYCODE_HOME, for some reason. In fact, if you maintain the back button pressed, you will see several ACTION_DOWN (0) events in a row (and much more if you return false; instead). Tested in an Eclair emulator and a Samsung Captivate (custom Froyo ROM).

Aleadam
  • 40,203
  • 9
  • 86
  • 108
  • That doesn't help. First of all, adding an onKeyListener and using onKey will only capture input from a keyboard, not hardware buttons such as the 'back', 'home', etc buttons. It is quite obvious that the event with onKeyDown ALWAYS has ACTION_DOWN as its action, and onKeyUp has ACTION_UP. I get the impression you didn't read everything I wrote(and its not very long to read). – Jonathan May 03 '11 at 11:01
  • @Jonathan you might be right that it's not called (I did not test it particularly), but I did read your post. I suggested this option because of this: `Default implementation of KeyEvent.Callback.onKeyDown(): perform press of the view when KEYCODE_DPAD_CENTER or KEYCODE_ENTER is released, if the view is enabled and clickable.` (View reference). Perhaps KEYCODE_BACK is handled as the other two (contd). – Aleadam May 03 '11 at 14:12
  • and this: `onKeyDown(int, KeyEvent) Called when a new key event occurs. onKeyUp(int, KeyEvent) Called when a key up event occurs.` (http://developer.android.com/guide/topics/ui/custom-components.html) Notice that it really doesn't say "Called when a new key **down** event occurs". That leads to an ambiguity that allows a different implementation for different `KEYCODE`s. That said, I did not read the source code for the OnKeyListener.java file to be sure of any of this. – Aleadam May 03 '11 at 14:14
  • @Jonathan I did a little more research on this. See above the updated answer. – Aleadam May 03 '11 at 15:14
  • @Aleadam I couldn't seem to get onKeyPreIme working with my SurfaceView, but I tried `public boolean dispatchKeyEvent(KeyEvent event)`(seems to be the equivalent onKeyPreIme for the Activity) but the results are the same, ACTION_DOWN and ACTION_UP seem to be called at the same time: when the button is released. I would appreciate it if you could try on your device. I want to know if this is only my device or it is the same thing for everyone. – Jonathan May 03 '11 at 21:42
  • @Aleadam ok well for me, with that exact code, the pop up only appears once the button is released, so I guess it must be my device - please confirm that it the pop up appears when the button is pressed(not when it is released) on your device. – Jonathan May 04 '11 at 00:11
  • @Jonathan as I said above, the code is working on both my phone and the emulator. That means that both the log `**dispatchKeyEvent** 0` and the `Toast` appear when I press the back key, not when I release it. To test it, I maintained several seconds the key pressed, watching in real time on a ddms window, many log lines and the popup. – Aleadam May 04 '11 at 00:16
  • http://stackoverflow.com/questions/5890149/android-2-x-input-issue I found the source of the problem and asked a new question – Jonathan May 04 '11 at 21:37
  • @ Jonathan good find. I wonder if it was reverted after, because I do not have that issue (as I said before, I tested it in a 2.1-rev 1 emulator and a 2.2 device). – Aleadam May 04 '11 at 22:18