I need to use volume buttons to control a variable parameter in my application.
I use Activity.onKeyDown
to get notified when the button is pressed but the media volume is also increased.
- increase media / ringtone volume
- pass the event to my application
Is there a way to avoid increasing the system volume and use volume key only for my application?
You need to capture all actions:
@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);
}
}
The next would be better because a long click for KeyEvent.KEYCODE_VOLUME_UP
does not work right in the previous answer.
@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);
}
}
Just to complete the previous answers, if you want long click support you should check how long the key was down using:
event.getEventTime() - event.getDownTime() > ViewConfiguration.getLongPressTimeout()
In the end the code will look like this:
@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_UP) {
if (event.getEventTime() - event.getDownTime() > ViewConfiguration.getLongPressTimeout()) {
//TODO long click action
} else {
//TODO click action
}
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_UP) {
if (event.getEventTime() - event.getDownTime() > ViewConfiguration.getLongPressTimeout()) {
//TODO long click action
} else {
//TODO click action
}
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
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;
}
Volume Button Usage in Fragments
If you desire to implement this in fragments bound the Activity ,you can use as:
Notice:fragment_words is just a layout name which is used arbitarly
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_words, container, false);
rootView.requestFocus();
rootView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCOD_VOLUME_DOWN ) {
//TODO SOMETHING
return true;
} else {
return false;
}
}
});}
volume with double click action
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
i++;
Handler handler= new Handler();
Runnable runnable=new Runnable() {
@Override
public void run() {
i=0;
}
};
if(i==1){
Toast.makeText(getApplicationContext(),"single click",Toast.LENGTH_SHORT).show();
handler.postDelayed(runnable,400);
}
else if(i==2){
Vibrator vb = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vb.vibrate(100);
}
return true;
}
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
i had a problem with the AB shutter (bluetooth) always launching the volume up, while i wanted to use the bluetooth keyevent for something else. but i still wanted the volume up to work when coming from the device's volume up button. the solution i found was to handle short events for my purpose - and to allow volume up change only if pressing on the device's button for over a second. see code:
boolean bVolumeUpKeyDown = false;
long StartDownMS = 0;
@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_UP) {
// my handling of keyevent
return true;
}
else if (action == KeyEvent.ACTION_DOWN) {
if(bVolumeUpKeyDown == false) {
bVolumeUpKeyDown = true;
StartDownMS = System.currentTimeMillis();
}
else if(System.currentTimeMillis() - StartDownMS > 1000)
return super.dispatchKeyEvent(event); // normal volume up handling
}
return true;
case KeyEvent.KEYCODE_ENTER:
if (action == KeyEvent.ACTION_UP) {
//my handling of second ab shutter button
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
精彩评论