Some Android programs trigger the "media volume" slider when the hardware volume up/down buttons are pressed. My application seems to set the ringer volume when the hardware buttons are pressed.
How would I enable the media volume slider?
I would hate for users to have to go into their settings to change the media volume when they use my application.
Just call Activity.setVolumeControlStream(AudioManager.STREAM_MUSIC) in your Activity's onCreate method.
private AudioManager audio;
Inside onCreate:
audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Override onKeyDown:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
audio.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
return true;
default:
return false;
}
}
Related
I cannot get an Android app (running on Android 6.0) to respond to volume key presses when the android.widget.MediaController is showing.
The media controller is shown by a fragment when a button in the fragment is tapped.
The activity that has loaded the fragment has the following code in onCreate:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
When the media controller is not showing, the volume key presses do adjust the volume and this volume adjustment does impact on the volume with which the sound is played by the media controller.
However, when the media controller is shown visible in the app, then the volume keys are ignored. I have overridden the onKeyDown method of the activity to detect when the key presses are recognised, and they are only recognised when the media controller is not visible.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
Log.i(TAG, "Increased volume");
getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
Log.i(TAG, "Decreased volume");
getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
return true;
default:
return false;
}
}
Users will tend to want to adjust volumes when the sound is being heard and this is exactly when they cannot adjust volumes, the way things are working. How can the media controller behaviour be changed so that it recognises the volume key presses?
Had this issue yesterday and stumbled upon your question. I know it's rather old and you've probably found a way around it but I thought I should post an answer in case someone else finds their way here.
Your initial idea helped a lot but instead of overriding the handler for KeyEvents for my activity I did so for the MediaController.
What I did was override public boolean dispatchKeyEvent(KeyEvent event) and initialise my MediaController object like this:
mediaControls = new MediaController(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_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
}
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
}
break;
default:
return super.dispatchKeyEvent(event);
}
return true;
}
};
audioManager is a private member in my Activity and is created the same way as in the question above.
Hope this will help someone.
Have a productive day!
Is there a way to disable/override the volume overlay/toast ? (its not actually a real toast)
I want to replace it, I already wrote a system Overlay which acts like the original, plus there are more sliders.
Now I just want to disable the original (image below) so it is not displayed.
You can try to override the following function to diable the volume buttons:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
boolean result;
switch( event.getKeyCode() ) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
result = true;
break;
default:
result= super.dispatchKeyEvent(event);
break;
}
return result;
}
I created customized media player to play videos. i have volume button if click that button i just call device volume settings like this
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.FLAG_SHOW_UI);
in my media player settings if i set disable volume control i don't want to show volume even click device side volume up/down button.
Any help is greatly appreciated!!!!!!
you can try overriding the volume key event
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP)
return true;
else
return false;
}
To help answer your intended outcome behaviour; 'i don't want to show volume even click device side volume up/down button'
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
switch( event.getKeyCode() ) {
case KeyEvent.KEYCODE_VOLUME_UP:
// do something
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:
// do something
break;
default:
super.dispatchKeyEvent(event);
break;
}
return true;
}
will make it so that the volume does not get changed when you press down.
You can Try this Statement
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
instead of
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.FLAG_SHOW_UI);
is there a way to hide the volume change bar/notification (however you might call it..btw. how do you call it?) ?
i attached a screenshot above. this bar is shown everytime i change the volume (at least on my nexus test device). or is this a nexus special?
It is the default post-honeycomb volume slider which appears when you press volume up/down buttons.
You cannot hide it in every screen of the system, but you can hide it in your activities.
Add this to an activity where you want to hide it and change the volume manually. Or you can just do nothing in case KeyEvent.KEYCODE_VOLUME_UP / DOWN if you don't want to change the volume. Remember to return true which menans you consumed the event. If you return false out there you will get double effect when the default volume behaviour will be triggered after your code.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_VOLUME_UP:
manager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
manager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
return true;
default:
return super.onKeyDown(keyCode, event);
}
}
Where AudioManager manager is retrieved as
manager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
Kotlin version for custom handling/ignoring:
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
return when(event?.keyCode){
KeyEvent.KEYCODE_VOLUME_DOWN->{
true //Do what you want or just return here
}
KeyEvent.KEYCODE_VOLUME_UP->{
true//Do what you want or just return here
}
else->super.onKeyDown(keyCode, event)
}
}
Used the following code to capture volume control button events.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
int action = event.getAction();
Log.i("Volume", "Volume " + keyCode + " " + action);
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_DOWN) {
audio.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
audio.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
}
return true;
default:
return super.onKeyDown(keyCode, event);
}
}
but when the volume bar toast is shown it doesn't capture the volume button press events anymore unless the toast is gone.
Any solution?
Since you seem to just capture the button presses to adjust the volume, maybe you should instead just call setVolumeControlStream() when initializing your Activity?
From the developer site:
You may be tempted to try and listen for volume key presses and modify the volume of your audio stream that way. Resist the urge. Android provides the handy setVolumeControlStream() method to direct volume key presses to the audio stream you specify.