51

I know you guys are probably tired of these kinds of posts, but why doesn't anything happen when I press volume down? I'm just trying to make a simple code, but apparently it's not working.

package com.cakemansapps.lightwriter;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.view.KeyEvent;
import android.util.Log;

public class LightWriter extends Activity implements OnTouchListener {
private static final String TAG = "Touch" ;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
}

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) 
{
    Log.w("LightWriter", "I WORK BRO.");
    return true;
}
return super.onKeyLongPress(keyCode, event);
}

public boolean onTouch(View view, MotionEvent me) {
    throw new UnsupportedOperationException("Not supported yet.");
}

}
FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
t3hcakeman
  • 2,289
  • 4
  • 25
  • 27
  • related: http://stackoverflow.com/questions/7493531/trying-to-catch-the-volume-onkeylongpress-not-working – whostolemyhat Feb 06 '12 at 15:46
  • Don't you need to associate your key event with controls? Did you check this link http://www.vogella.de/articles/AndroidMedia/article.html – kosa Feb 06 '12 at 15:48
  • [Here you go.](http://stackoverflow.com/a/2875006/420015) – adneal Feb 06 '12 at 15:57

5 Answers5

69

I don't know if you can get long press events for the hardware keys.

I've used this code to listen for the volume button before.

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

If that doesn't work for you let us know what device you are testing on.

Kotlin

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
        // Do something
    }
    return true
}
charles92
  • 3
  • 3
FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
  • 1
    Should the "returns true" line be inside of the 'if' block and by default it should return false? You should only return true if you handled the event. – Birdnado Apr 29 '14 at 21:33
  • 24
    The last line should be "return super.onKeyDown(keyCode, event);" instead of "return true". – TechAurelian May 09 '14 at 15:31
  • 3
    This code is correct, but it will disable the main purpose which is to lessen the volume. it will prioritize the statement in the `//Do something part` – ajdeguzman Aug 01 '14 at 03:21
  • 2
    @ajdeguzman if you return false, instead of true, I think it will also change the volume accordingly. – FoamyGuy Aug 01 '14 at 14:19
  • 3
    Awesome. How do I know which volume is it lowering?... For example, if it's the System or Music or Alarm? – Si8 Nov 21 '16 at 21:37
  • Thanks you saved my time...+1 for that – Sagar Aghara Apr 11 '17 at 05:56
  • @AnAurelian return true will make volume button "disabled". So you can run the code without changing the volume. – Chris Maverick Sep 18 '17 at 06:59
17

Another approach

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    int action = event.getAction();
    int keyCode = event.getKeyCode();
        switch (keyCode) {
        case KeyEvent.KEYCODE_VOLUME_UP:
            if (action == KeyEvent.ACTION_DOWN) {
                //TODO
            }
            return true;
        case KeyEvent.KEYCODE_VOLUME_DOWN:
            if (action == KeyEvent.ACTION_DOWN) {
                //TODO
            }
            return true;
        default:
            return super.dispatchKeyEvent(event);
        }
    }
Zar E Ahmer
  • 33,936
  • 20
  • 234
  • 300
8
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
        // ... your code
        return true;
    } else if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
        // ... your code
        return true;
    } else
        return super.onKeyDown(keyCode, event);
}
Micer
  • 8,731
  • 3
  • 79
  • 73
Hamidreza Sadegh
  • 2,155
  • 31
  • 33
5

try these. just tested them:

@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
    super.onKeyLongPress(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        Log.w("LightWriter", "I WORK BRO.");
        return true;
    }
    return false;
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
        Log.w("LightWriter", "I WORK BRO.");
        return true;
    }
    return true;
}
alexrnov
  • 2,346
  • 3
  • 18
  • 34
Sergey Benner
  • 4,421
  • 2
  • 22
  • 29
  • @Sergery can you tell me how it work when device is locked – Abhishek Sep 29 '16 at 09:39
  • 1
    @Abhishek I've never done this... but my understanding/guess is: Your app would need permission to run when screen is locked( http://stackoverflow.com/a/11546168/2801237) and/or would likely need to setup a broadcast receiver to receive the key event (possibly one of these(and it 'might' change which device is used) https://developer.android.com/reference/android/media/AudioManager.html ) (Sorry for ambiguity(I usually work on ContentProviders, Services, IPC, etc.), but hope this helps lead down right path) – mawalker Nov 09 '16 at 20:02
  • onKeyLongPress() didn't work by me. However onKeyDown() works. Seems to be device dependent. – ka3ak Jun 14 '18 at 06:11
  • Ok, I know what the problem was. I had to call event.startTracking() in onKeyDown(). After that the onKeyLongPress() was called. – ka3ak Jun 14 '18 at 06:30
4

use this code to handle Volume key event

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    super.onKeyUp(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
    {
        Toast.makeText(MainActivity.this,"Up working",Toast.LENGTH_SHORT).show();
        return true;
    }
    return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
    {
        Toast.makeText(MainActivity.this,"Down working",Toast.LENGTH_SHORT).show();
        return true;
    }
    return false;
}
Learn Pain Less
  • 2,274
  • 1
  • 17
  • 24
  • 3
    Although this might be working, the approach is I believe wrong. If you check the docs, `onKeyDown` is called when ANY button is pressed, `onKeyUp` is called when ANY button press is released. You can handle both `KeyEvent.KEYCODE_VOLUME_UP` and `KeyEvent.KEYCODE_VOLUME_DOWN` in one of them. – Micer Nov 23 '17 at 08:56