I noticed that regardless of the volume I set my phone, the sound for a button click in my app remains the same regardless, how can I synchronize it with the phone's system volume? Here's the code format I used
Mediaplayer buttonSoundClick;
buttonClickSound = MediaPlayer.create(this, R.raw.button_click_sound);
buttonClickSound.start();
buttonClickSound = MediaPlayer.create(this, R.raw.button_click_sound);
} private void prepareAsync() {
buttonClickSound.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onClick(View v) {
//Button Click Sound
buttonClickSound.start();
Android has different volume levels for different stream types.
Override onKeyDown() and add the following code.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
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;
}
}
After this, try playing around with the stream types to get it right for your app. The stream types available are:
AudioManager.STREAM_MUSIC
AudioManager.STREAM_RING
AudioManager.STREAM_ALARM
AudioManager.STREAM_SYSTEM
AudioManager.STREAM_NOTIFICATION
OR
You could directly set the MediaPlayer stream type by using MediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
Buy, you must call this method before prepare() or prepareAsync() in order for the target stream type to become effective thereafter.
Related
I'm trying to make a application that switches the audio play between the speaker and earpiece.
I'm using The following code:
public boolean setAudioMode(String mode) {
AudioManager audioManager =
(AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0);
if (mode.equals("earpiece")) {
audioManager.setMode(AudioManager.STREAM_MUSIC);
audioManager.setSpeakerphoneOn(false);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
return true;
} else if (mode.equals("speaker")) {
audioManager.setMode(AudioManager.STREAM_MUSIC);
audioManager.setSpeakerphoneOn(true);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
return true;
}
return false;
}
This code is working and I can change the audio output correctly.
But after I close my application, my phone does not play any sound through my headphones and the volume control sticks to in call volume. My phone only go back to normal after a full restart.
What can I do to restore the phone audio? Or is there a better way to switch the audio output that does not make this problem?
I try to make simple mediaplayer app just for personal/educational purpose (play specific mp3 file) but i have a problem with others apps. I use services to play sound in background. Everything working fine but when i turn another media app i still can play simultaneously different song. How to "tell" to the system that my app is using mediaplayer and no ones can use mediaplayer till my services end. I use AudioManager STREAM_MUSIC and start playing my song when i get AUDIOFOCUS_GAIN checked by AUDIOFOCUS_REQUEST_GRANTED.
to play my music and set the foreground notification i use
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (AudioManager.AUDIOFOCUS_REQUEST_GRANTED == result) {
this.startForeground();
player.start();
}
You have to use media players audio focus implementations, detail documentation here:
http://developer.android.com/guide/topics/media/mediaplayer.html#audiofocus
Audio focus is one of the thing which assign to any application who request for that, means if you request for that, any other application using it will stop automatically & you;ll start using audio , same case while you are using it if any other app request for it, your audio will be stopped. You will be notifyed of the loss of audio focus through the onAudioFocusChange handler of the Audio Focus Change Listener you registered when requesting the audio focus
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
int result = am.requestAudioFocus(focusChangeListener,
// Use the music stream.
AudioManager.STREAM_MUSIC,
// Request permanent focus.
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// other app had stopped playing song now , so u can do u stuff now .
}
private OnAudioFocusChangeListener focusChangeListener =
new OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
AudioManager am =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
switch (focusChange) {
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) :
// Lower the volume while ducking.
mediaPlayer.setVolume(0.2f, 0.2f);
break;
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) :
pause();
break;
case (AudioManager.AUDIOFOCUS_LOSS) :
stop();
ComponentName component =new ComponentName(AudioPlayerActivity.this,MediaControlReceiver.class);
am.unregisterMediaButtonEventReceiver(component);
break;
case (AudioManager.AUDIOFOCUS_GAIN) :
// Return the volume to normal and resume if paused.
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.start();
break;
default: break;
}
}
};
I am using MediaPlayer to play a sound and below is my code
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound);
mediaPlayer.setLooping(true);
mediaPlayer.setVolume(0.5f, 0.5f);
mediaPlayer.start();
the MediaPlayer plays the sound in the given volume but the volume can be increased or decreased using the hardware key. I want to know if there is a way to keep the volume for my mediaPlayer fixed no matter what volume the user keeps using the hardware key
Thanks in advance
AFASIK Media Player does not provide any such Listener. You need to override key press events for checking that
#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);
}
}
MediaPlayer provide isPlaying boolean to know either mediaPlayer is in use, you can use that in conjunction with KeyPress events.
I have and app with an audio player and video player. I want when the audio player is playing in background and I start the video, the audio player to stop itself.
I could achieve this easily with a broadcast receiver by sending an intent when opening the Video, and listen for that intent in Audio player and stop it in onReceive().
However, I would like to extend this feature not only to my audio player, but to all audio players. So I thought if there's a standard intent to send when the video player opens?
You should use audio focus for this. Cf the RandomMusicPlayer sample android project:
public class AudioFocusHelper {
AudioManager mAM;
MusicFocusable mFocusable;
private final AudioManager.OnAudioFocusChangeListener listener = new AudioManager.OnAudioFocusChangeListener() {
#Override
/**
* Called by AudioManager on audio focus changes. We implement this by calling our
* MusicFocusable appropriately to relay the message.
*/
public void onAudioFocusChange(int focusChange) {
if (mFocusable == null) return;
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
mFocusable.onGainedAudioFocus();
break;
case AudioManager.AUDIOFOCUS_LOSS:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
mFocusable.onLostAudioFocus(false);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mFocusable.onLostAudioFocus(true);
break;
default:
}
}
};;
public AudioFocusHelper(Context ctx, MusicFocusable focusable) {
mAM = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
mFocusable = focusable;
}
/** Requests audio focus. Returns whether request was successful or not. */
public boolean requestFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
mAM.requestAudioFocus(listener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
/** Abandons audio focus. Returns whether request was successful or not. */
public boolean abandonFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED == mAM.abandonAudioFocus(listener);
}
}
Can I change the media volume? and how? I used this so far:
setVolumeControlStream(AudioManager.STREAM_MUSIC);
But have a seekbar and want to change the media volume, not ring volume.
So can someone show me how to just change the media volume at onCreate() and I fix the seekbar later.
The right method to use would be setStreamVolume on your AudioManager. It could looks like this
AudioManager audioManager =
(AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
[int value],
[if desired a flag]);
An example use of the flag is to get the beep when setting the volume so the user can hear the outcome. The flag for that would be AudioManager.FLAG_PLAY_SOUND.
You could use AudioManager.FLAG_SHOW_UI if you don't want to play a sound but display a toast with the current value. The use has to get a feedback tho. Doesn't matter if it is audible or visual.
To get the maximal valid value for the given stream you just call getStreamMaxVolume() on the AudioManager and get an integer back which represents ... well the maximal valid value for the volume.
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;
// Update based on #Rene comment below:
return super.onKeyDown(keyCode, event);
}
}
You can use the following code to handle Volume using a SeekBar:
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
SeekBar sbVolumeBooster = (SeekBar) findViewById(R.id.sbVolumeBooster);
sbVolumeBooster.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
sbVolumeBooster.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
sbVolumeBooster.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
#Override
public void onStopTrackingTouch(SeekBar arg0)
{
}
#Override
public void onStartTrackingTouch(SeekBar arg0)
{
}
#Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2)
{
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
progress, 0); // 0 can also be changed to AudioManager.FLAG_PLAY_SOUND
}
});
Giving a 0 - in the flags avoids getting a visual and audio indicator .
That's good when you implement your own audio bar and indicator and you don't want android to add anything.
Use adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, flags);
http://developer.android.com/reference/android/media/AudioManager.html#adjustStreamVolume(int, int, int)