3

Regarding to that question and that question if you use onKeyDown and onKeyLongPress one need to use event.startTracking(); inside onKeyDown. But I use WebViews.

What can I do to join onKeyDown and onKeyPress while not losing WebView's back function ?
I need this behaviour:
Inside webview,
* When user presses back button, webview will go back in history
* When user long presses back key, finish() will be called

public boolean onKeyDown(int keyCode, KeyEvent event) {
     if (keyCode == KeyEvent.KEYCODE_BACK) {
         if(mWebView.canGoBack()) {
             mWebView.goBack();
         } else {
             super.onBackPressed();
         }
         return true;
      }
     return super.onKeyDown(keyCode, event);
 }

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK)
    {
        finish();
        return true;
    }
    return super.onKeyLongPress(keyCode, event);
}
Community
  • 1
  • 1
trante
  • 33,518
  • 47
  • 192
  • 272

2 Answers2

2

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;
}
corsair992
  • 3,050
  • 22
  • 33
  • @trante: Did you override the `onKeyLongPress()` as shown in my edit? – corsair992 Jan 14 '14 at 18:45
  • @trante: Can you confirm that your `targetSdkVersion` is set to 5 or higher in your manifest. Otherwise the `onKeyLongPress()` method should be called. It's working for me on a Galaxy S2 device. – corsair992 Jan 14 '14 at 19:30
  • I checked your last edited. Works like a charm. Thanks. – trante Jan 16 '14 at 22:43
0

Take a look at this answer.

Basically you use a handler in your onTouchEvent to detect a long press.

Hope it helps!

Community
  • 1
  • 1
Alessandro Roaro
  • 4,665
  • 6
  • 29
  • 48
  • I tried. I added ```mySuperWebView.setOnTouchListener(new View.OnTouchListener() {```. This listener captures ```MotionEvent.ACTION_DOWN```, ```MotionEvent.ACTION_MOVE``` etc. But it doesn't capture back button press with ```MotionEvent.BUTTON_BACK```. So doesn't work. – trante Jan 10 '14 at 23:13