Onkeydown and Onkeylongpress

onKeyDown and onKeyLongPress

Here is the code that I wrote. It works like a charm. May be you can optimize it for better logic. But you will get the point with it. The key is to use flags. Short press is a press where we press volume button for short time and release. So onKeyUp is the one which will help us detect short presses.

package com.example.demo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;

public class TestVolumeActivity extends Activity {
boolean flag = false;

boolean flag2 = false;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_splash_screen, menu);
return true;
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
Log.d("Test", "Long press!");
flag = false;
flag2 = true;
return true;
}
return super.onKeyLongPress(keyCode, event);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
event.startTracking();
if (flag2 == true) {
flag = false;
} else {
flag = true;
flag2 = false;
}

return true;
}
return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {

event.startTracking();
if (flag) {
Log.d("Test", "Short");
}
flag = true;
flag2 = false;
return true;
}

return super.onKeyUp(keyCode, event);
}
}

Logcat for all long presses(No short press detected):

10-18 02:06:15.369: D/Test(16834): Long press!
10-18 02:06:18.683: D/Test(16834): Long press!
10-18 02:06:21.566: D/Test(16834): Long press!
10-18 02:06:23.738: D/Test(16834): Long press!

Logcat for all short presses:

10-18 02:07:42.422: D/Test(16834): Short
10-18 02:07:43.203: D/Test(16834): Short
10-18 02:07:43.663: D/Test(16834): Short
10-18 02:07:44.144: D/Test(16834): Short

Trying to catch the Volume onKeyLongPress() not working

You are almost there. You need to detect the same key event in the onKeyPress handler and start tracking it so that the long press can work. Here's the code you need:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
event.startTracking();
return true;
}
return super.onKeyDown(keyCode, event);
}

onKeyLongPress not working for KeyboardKey

For soft keyboard, you should use proper timer to handle long press event like any other applications. LatinIME also uses this solution, please check out.

PointerTracker.onDownEventInternal.startLongPressTimer()

Android onKeyLongPress when webview exists

You need to override the onBackPressed() method instead of onKeyDown(), which is called from onKeyUp() post-Eclair unless the target SDK is set to lower than Eclair. Returning true from onKeyLongPress() will cause the event to be cancelled, and onBackPressed() won't be called.

@Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
&& !event.isCanceled() {
super.onBackPressed();
return true;
}
return false;
}

Edit: Actually you should override the onKeyUp() method instead to provide the same experience, and set a flag on the onKeyLongPress() call to check if it has been long pressed:

private boolean isBackKeyLongPressed;

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
&& !event.isCanceled()) {
if (!isBackKeyLongPressed && mWebView.canGoBack()) {
mWebView.goBack();
} else {
onBackPressed();
}
isBackKeyLongPressed = false;
return true;
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
isBackKeyLongPressed = false;
}
return super.onKeyUp(keyCode, event);
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
isBackKeyLongPressed = true;
}
return false;
}

Android onKeyLongPress

Ok, I have found a solution. Not the best, but it works.
OnKeyDown and OnKeyLongPress are still the same, but OnKeyUp is now this:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(!event.isCanceled()){
switch(keyCode){
case KeyEvent.KEYCODE_VOLUME_UP:
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
break;
}
}
return super.onKeyUp(keyCode, event);
}

How to differentiate between long key press and regular key press?

The reason why onKeyLongPress is never called, is that you return true in onKeyDown without telling the framework that this might be a long press - causing the KeyEvent to stop its flow through the different event handlers.

What you need to do is this:

  1. Before you return true, call event.startTracking() as explained in the documentation.
  2. Handle the long press in onKeyLongPress.

Implement as 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 );
}


Related Topics



Leave a reply



Submit