I know the question can be regarded as "politically incorrect", but I'm designing an app which "by design" must get the attention of people within the maximum possible distance range, otherwise it will not be used... :-)
I'm currently using SoundManager class, and this is the code which plays my ogg clip:
public void playSound(int index) {
int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 0, 0, 1.0f);
}
The problem is that the sound volume I get the clip played with appears to be dependent by "Settings/Audio/Voulme" settings the user has set. Instead it appears to be indipendent by the hardware volume buttons setting.
Is there a way for an Android app to play a sound to the maximum physical volume allowed by the device?
I'd suggest using getStreamMaxVolume and setStreamVolume to do this:
int origionalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
Then once you're done just set it back to the original volume.
I think I was beaten to the punch, ahh well :)
Some code that actually does this, I'm using the MediaPlayer rather than the soundpool as this gives you a play complete callback which doesn't appear to be present on the soundpool:
final AudioManager mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
final int originalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
MediaPlayer mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource("content://media/internal/audio/media/97");
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0);
}
});
Btw the with call mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 0, 0, 1.0f); the streamVolume values are actually floats 0 -> 1 that represent a percentage of the maximum value so you'd really just want to put in 1.0f there.
You can adjust the settings before playing the audio.
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.getStreamMaxVolume(), 0);
float count=100*.01f;
MediaPlayer mp=new MediaPlayer();
mp.setLooping(false);
mp = MediaPlayer.create(ActivityName.this, myUri);
mp.setVolume(count,count);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
mp.stop();
}
});
Both of these codes worked for me but I prefer the one from MediaPlayer
AudioManager audioManager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND);
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
MediaPlayer mp=new MediaPlayer();
mp.setLooping(false);
mp = MediaPlayer.create(HomeActivity.this, notification);
mp.setVolume(count,count);
mp.start();
});
That's the wrong code.
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
Related
I want to set volume for an alarm. I use this code but nothing seems to happen with the volume, only logs show value of volume that I'd set. What should I do to actually change volume?
My code:
final MediaPlayer mediaPlayer = MediaPlayer.create(this, RingtoneManager.getActualDefaultRingtoneUri(this,RingtoneManager.TYPE_ALARM));
final AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
final int currentVolume = audio.getStreamVolume(AudioManager.STREAM_ALARM);
Log.e("Point_1", "Volume " + currentVolume);
audio.setStreamVolume(AudioManager.STREAM_ALARM,0,0);
mediaPlayer.start();
new Timer().schedule(new TimerTask() {
#Override
public void run() {
mediaPlayer.stop();
Log.e("Point_1", "Volume_after " + audio.getStreamVolume(AudioManager.STREAM_ALARM));
}
}, 5000);
Thanks.
use this code
AudioManager audioManager =
(AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
[int value],
[if desired a flag]);
you should use AudioManager.STREAM_MUSIC instead of AudioManager.STREAM_ALARM
and see How to correctly set MediaPlayer audio stream type too
I customised an alarm clock, but it didn't work when the phone was in silent mode.
mediaPlayer = new MediaPlayer();
mediaPlayer = MediaPlayer.create(this, R.raw.example);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.start();
What could be the problem?
Volume of MediaPlayer depends on volume of AudioManager for STREAM_MUSIC.
For instance, set volume to max for stream music, before play your sound, and maybe after re-set value to old value (0):
This solution not respect choice of user. He doesn't to be disturb if he put device in silent mode !
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0);
I am trying to stream voice/audio (two way) between two Android devices Tablet and Mobile (over java sockets).
The Tablet can play received audio(voice) clearly, but the Mobile plays received audio as noise.
Then i set this audio mode in the code on tablet:
audioManager.setMode(AudioManager.MODE_IN_CALL);
This now results in Mobile receiving clear voice.
But the tablet goes silent, it does not play the received audio (or rather its not audible).
I am not sure what combination (if any) of AudioManager mode i should use here?
It's possible to handle the sound you want to play as Alarm.
Create a new class named AlarmController and try this code.
This worked for me on Android 4.4.2 (Huawei ascend P7) with each system volume (Media, Ringtone, Alarm) set to 0.
Context context;
MediaPlayer mp;
AudioManager mAudioManager;
int userVolume;
public AlarmController(Context c) { // constructor for my alarm controller class
this.context = c;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
//remeber what the user's volume was set to before we change it.
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
mp = new MediaPlayer();
}
public void playSound(String soundURI){
Uri alarmSound = null;
Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
try{
alarmSound = Uri.parse(soundURI);
}catch(Exception e){
alarmSound = ringtoneUri;
}
finally{
if(alarmSound == null){
alarmSound = ringtoneUri;
}
}
try {
if(!mp.isPlaying()){
mp.setDataSource(context, alarmSound);
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.setLooping(true);
mp.prepare();
mp.start();
}
} catch (IOException e) {
Toast.makeText(context, "Your alarm sound was unavailable.", Toast.LENGTH_LONG).show();
}
// set the volume to what we want it to be. In this case it's max volume for the alarm stream.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM), AudioManager.FLAG_PLAY_SOUND);
}
public void stopSound(){
// reset the volume to what it was before we changed it.
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, userVolume, AudioManager.FLAG_PLAY_SOUND);
mp.stop();
mp.reset();
}
public void releasePlayer(){
mp.release();
}
I hope this works for you. :)
I am creating a notification with Android's NotificationManager.
Is it possible to 'override' the phone's volume (mute) settings in such a way, that the notification's sound is ALWAYS played?
The reason I need this is the following:
The notification is so important, that vibration alone may not be enough. The user MUST be alerted. So a sound shall be played, even if the phone is muted or the volume is very low.
yes it is possible,
MediaPlayer mMediaPlayer;
Uri notification = null;
notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_ALARM);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(ctx, notification);
// mMediaPlayer = MediaPlayer.create(ctx, notification);
final AudioManager audioManager = (AudioManager) ctx
.getSystemService(Context.AUDIO_SERVICE);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.prepare();
// mMediaPlayer.start();
mMediaPlayer.setLooping(true);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer arg0) {
mMediaPlayer.seekTo(0);
mMediaPlayer.start();
}
});
You can change RINGING mode like this from silent to normal
AudioManager mobilemode = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mobilemode.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
// Turn on all sound
// turn on sound, enable notifications
mobilemode.setStreamMute(AudioManager.STREAM_SYSTEM, false);
//notifications
mobilemode.setStreamMute(AudioManager.STREAM_NOTIFICATION, false);
//alarm
mobilemode.setStreamMute(AudioManager.STREAM_ALARM, false);
//ringer
mobilemode.setStreamMute(AudioManager.STREAM_RING, false);
//media
mobilemode.setStreamMute(AudioManager.STREAM_MUSIC, false);
// Turn off all sound
// turn off sound, disable notifications
mobilemode.setStreamMute(AudioManager.STREAM_SYSTEM, true);
//notifications
mobilemode.setStreamMute(AudioManager.STREAM_NOTIFICATION, true);
//alarm
mobilemode.setStreamMute(AudioManager.STREAM_ALARM, true);
//ringer
mobilemode.setStreamMute(AudioManager.STREAM_RING, true);
//media
mobilemode.setStreamMute(AudioManager.STREAM_MUSIC, true);
FOR YOUR CASE YOU CAN TRY SOMETHING LIKE THIS
int previousNotificationVolume =mobilemode.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
mobilemode.setStreamVolume(AudioManager.STREAM_NOTIFICATION,mobilemode.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION), 0);
// Play notification sound
// Set notification sound to its previous
mobilemode.setStreamVolume(AudioManager.STREAM_NOTIFICATION,previousNotificationVolume, 0);
In my app, I use the following code to play a short notification sound using MediaPlayer with STREAM_NOTIFICATION. The issue is that, when the app plays the notification sound and at the same time music is played at background by music player app, the notification sound will interrupt (pause) the music playing. How can I make my app's notification sound to be played simultaneously with the background music playback? Thanks.
AssetFileDescriptor afd =
mResources.openRawResourceFd(resId);
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
mediaPlayer.prepare();
mediaPlayer.start();
The behaviour described in the question seems to be specific for Android 5.x and below. For Android 6.x and above AudioManager behavior has changed and AudioSystem.STREAM_NOTIFICATION flag doesn't interrupt music playback anymore.
As workaround I would recommend to replace
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
by
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
P.S. Not sure what exactly changed in Android platform but according to
https://android.googlesource.com/platform/frameworks/base/+/android-5.1.1_r37/media/java/android/media/AudioAttributes.java and https://android.googlesource.com/platform/frameworks/base/+/android-6.0.0_r26/media/java/android/media/AudioAttributes.java they treat AudioSystem.STREAM_NOTIFICATION as AudioSystem.STREAM_SYSTEM for both Android 5.x & 6.x:
public Builder setInternalLegacyStreamType(int streamType) {
switch(streamType) {
/*...*/
case AudioSystem.STREAM_SYSTEM:
mContentType = CONTENT_TYPE_SONIFICATION;
break;
/*...*/
case AudioSystem.STREAM_NOTIFICATION:
mContentType = CONTENT_TYPE_SONIFICATION;
break;
/*...*/
default:
Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes");
}
mUsage = usageForLegacyStreamType(streamType);
return this;
}