How to distinguish between a long keystroke and a regular keystroke?

I am trying to override the functionality of pressing the back key. When the user clicks once, I want him to return to the previous screen. However, when the back key is pressed (for example, two seconds or more), I want to exit the application.

I am currently redefining these two methods in my work:

@Override public boolean onKeyDown( int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK) { //manage short keypress return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyLongPress( int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK) { //manage long keypress (different code than short one) return true; } return super.onKeyLongPress(keyCode, event); } 

But the onKeyLongPress never called because the event is always accepted by the onKeyDown method.

Is there a way to use both methods? Or do you need to do everything in onKeyDown and use the number of repetitions / milliseconds to detect it?

+7
source share
3 answers

The reason onKeyLongPress never called is because you are returning true to onKeyDown without telling the framework that it could be a long press, causing KeyEvent to stop the stream through various event handlers.

What you need to do is:

  • Before you return true, call event.startTracking() as described in the documentation .
  • Handle a long press on onKeyLongPress .

Decide as shown below and it will work:

  @Override public boolean onKeyDown( int keyCode, KeyEvent event ) { if( keyCode == KeyEvent.KEYCODE_BACK ) { event.startTracking(); return true; } return super.onKeyDown( keyCode, event ); } @Override public boolean onKeyUp( int keyCode, KeyEvent event ) { if( keyCode == KeyEvent.KEYCODE_BACK ) { //Handle what you want on short press. return true; } return super.onKeyUp( keyCode, event ); } @Override public boolean onKeyLongPress( int keyCode, KeyEvent event ) { if( keyCode == KeyEvent.KEYCODE_BACK ) { //Handle what you want in long press. return true; } return super.onKeyLongPress( keyCode, event ); } 
+12
source

Why not use onKeyUp() as well as onKeyDown() ? During onKeyDown() you don’t know whether a long press or not is because it is called as soon as a key is pressed, and you don’t know how long the user intends to keep the key pressed. As KasperMoerch correctly says, you need to call startTracking in your onKeyDown() method and return true . Then in onKeyUp() you can call event.isTracking() and event.isLongPress() to determine whether things should be handled like a long press or a short press.

+2
source

I think the best way to handle this is as such.

The only drawback that I see here is that a single click on the menu button does not produce sound if it is on. Perhaps there is a way to test this parameter and use it or invoke the default behavior.

the code:

 private boolean _handledMenuButton=false; @Override public boolean onKeyUp(final int keyCode,final KeyEvent event) { switch(keyCode) { case KeyEvent.KEYCODE_MENU: if (!_handledMenuButton) { //Handle single clicking here } _handledMenuButton=false; return true; } return super.onKeyUp(keyCode,event); } @Override public boolean onKeyLongPress(final int keyCode, final KeyEvent event) { switch(keyCode) { case KeyEvent.KEYCODE_MENU: //Handle long clicking here _handledMenuButton=true; return true; } return super.onKeyLongPress(keyCode,event); } @Override public boolean onKeyDown(final int keyCode,final KeyEvent event) { switch(keyCode) { case KeyEvent.KEYCODE_MENU: _handledMenuButton=false; event.startTracking(); return true; } return super.onKeyDown(keyCode,event); } 
+2
source

All Articles