2

How to check if both volume up and volume down buttons are pressed together for few seconds in Android device ?

And if pressed, I need to call a function. This detection should work if my application is installed in any android device. Any near solution will also do.

Aja
  • 23
  • 9

3 Answers3

3

You need to detect when the both of the keys are pressed using onKeyDown callback, something like should work:

public boolean up,down;

public boolean onKeyDown(int keyCode, KeyEvent event) {
   if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
      down = true;
   } else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
      up = true;
   }
   if(up && down) {
    // Two buttons pressed, call your function
   }
   return true;
}

public boolean onKeyUp(int keyCode, KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
    down = false;
  } else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
    up = false;
  }
  return true;
}
dan
  • 13,132
  • 3
  • 38
  • 49
  • And what can I do to check if it had been pressed for some amount of time, say 2 seconds ? – Abhishek Singh Apr 19 '18 at 06:20
  • You can use a new variable like: `upKeyTime = event.getEventTime();` to determine the amount of time that the key was pressed. – dan Apr 19 '18 at 06:24
  • 1
    just one more thing ! What should i do to make it work even when the application is in background or when the screen is off. Because this is for emergency application and i need to detect the buttons press even if the application is not running or the phone is locked. Is it possible? – Abhishek Singh Apr 19 '18 at 06:59
  • @AbhishekSingh `Is it possible?` no, it is not – pskink Apr 19 '18 at 07:06
  • @AbhishekSingh Unfortunately the keypress works only while the app is in foreground, and from a service you are not allowed to retrieved them. See here: https://developer.android.com/training/keyboard-input/index.html. But, you should create another question, maybe there are some workarounds. – dan Apr 19 '18 at 07:09
  • @dan thank you so much. It helped me a lot to proceed further. – Abhishek Singh Apr 19 '18 at 08:30
  • @AbhishekSingh You're welcome. You should vote/accept the answer it it helped. – dan Apr 19 '18 at 08:31
1

You need to override some methods and apply your logic there: for example, create following variables

private static final int PRESS_INTERVAL = 1000;
private long upKeyTime = 0;

Override the following

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (KeyEvent.KEYCODE_VOLUME_DOWN == event.getKeyCode()) {
            if ((event.getEventTime() - upKeyTime) < PRESS_INTERVAL) {
                Toast.makeText(this, "Pressed together", Toast.LENGTH_SHORT).show();
            }
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }


    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (KeyEvent.KEYCODE_VOLUME_UP == keyCode) {
            upKeyTime = event.getEventTime();
        }
        return super.onKeyUp(keyCode, event);
    }

This code will print a toast if the user presses volume down key after volume up key within 1 second. I hope you can change this code to the down-up key combination as this is the up-down combination.

Somesh Kumar
  • 8,088
  • 4
  • 33
  • 49
  • Thank you so much. This code worked. And do you know any way so that i can use this detection even when the phone is locked or the application is not opened? – Abhishek Singh Apr 19 '18 at 08:31
  • I am afraid this is not possible as stated [here](https://stackoverflow.com/questions/3454710/onkeydown-in-a-service-global-hot-keys) by @RomainGuy – Somesh Kumar Apr 19 '18 at 09:57
  • @AbhishekSingh Just a Note: You should change your selected answers too frequently. Yesterday you changed your selected answer many times.. and today you did the same. Just select the one which suits you. – Somesh Kumar Apr 20 '18 at 11:09
  • I am new here and i thought it is possible to mark more than one answer to be correct, so whenever I saw unchecked answer, i clicked on it, later I got to know about only one selection. Sorry and thank you :) – Abhishek Singh Apr 20 '18 at 23:31
1
public static final int VOLUME_PRESSED__INTERVAL = 100;
private long upKeyEventTime = 0;
private long downKeyEventTime = 0;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            downKeyEventTime = event.getEventTime();
        } else {
            upKeyEventTime = event.getEventTime();
        }
        if (Math.abs(upKeyEventTime - downKeyEventTime)<= VOLUME_PRESSED__INTERVAL){
            //TODO call your method
            return false;
        }
    }

    return super.onKeyDown(keyCode, event);
}

If you want more accuracy you can set VOLUME_PRESSED__INTERVAL = 0;

Alireza Barakati
  • 1,016
  • 2
  • 9
  • 23