Manually mute sound in Android app when in silent mode? - android

I have tried finding an answer to this, but my searches kept returning irrelevant results...
So the problem is - I am writing a game that plays sound effects (no music just yet), and I set the stream type to Music. However, when I put my phone in silent mode (no vibration either, if that matters) the app still plays sounds. I can turn off the sound in the app using the volume keys, but what I expected (and what my future users would probably expect too) was that the app won't make a sound when the phone is in silent mode.
At this point, I am not sure if this should be automatically managed by the OS, or if I am expected to do something about it. I can surely detect the silent mode, set the volume to 0 in e.g onResume, but that will probably overwrite the setting the users set up by pressing the volume buttons - so when they unmute the phone, the app either has to set the volume programmatically to a predefined value, or ideally, to a saved one from sharedPrefs... which sounds relatively cumbersome. Is there a nicer solution?
This is how I initialize & then use sounds:
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new SparseIntArray();
soundPoolMap.put(CLICK_1, soundPool.load(activity, R.raw.click1, 1));
soundPoolMap.put(CLICK_2, soundPool.load(activity, R.raw.click2, 2));
...
float volume = 1.0f;
soundPool.play(soundPoolMap.get(soundID), volume, volume, 1, 0, 1f);

What I understand from your question is you want to mute your app when device is on silent mode.
Try to check the the RingerMode every time before your app play sound/music and play sound only when the ringer RingerMode is normal.
Here is the sample code.
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
switch (audio.getRingerMode())
{
case AudioManager.RINGER_MODE_NORMAL:
// Device is on Normal mode.
// you can play music.
break;
case AudioManager.RINGER_MODE_SILENT:
// Device is on Silent mode.
// you should not play sound now.
break;
case AudioManager.RINGER_MODE_VIBRATE:
// Device is on Vibrate/Meeting mode.
// you should not play sound but you can make vibrate device (if you want).
break;
}

Related

How to Change Sound Programmatically on Android

I have a media player which plays song files. However, no matter how I try to initialize its volume, the only way to change it is manually with the volume buttons. I've tried
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume, 0); // Sets volume to max
and even
mMediaPlayer.setVolume(1, 1);
but none work. I've used this code in the past without problem. I've tried my app on both 5.1.1 and 7.1.1 and no luck. It doesn't matter whether the phone's volume starts in a muted state or not. I checked and maxVolume is non-zero (I've tried just hardcoding numbers too). How can I set the initial volume programmatically? The media player starts playing automatically. (I've tried calling this within the media player's onPrepared listener too in case it made a difference. It doesn't.) I also checked whether the phone volume is "fixed". It's not.
How can I get my player to start playing at max volume (no matter what the phone was set for)?
I found the problem. I had the stream wrong. Instead of STREAM_ALARM it should have been STREAM_MUSIC. The list of streams can be found here:
https://developer.android.com/reference/android/media/AudioManager.html

Android Media Player setVolume Issues

Until now, I was setting my MediaPlayer volume by setting the stream volume. I don't want to do that anymore because it messes with user settings. I now take the value from a SeekBar (0 to 100) and do valueFromSeekBar / 100 to get a float between 0 and 1 to use in MediaPlayer.setVolume(float, float).
The problem is that the volume level doesn't seem to change. Here is how I set up the MediaPlayer:
player.setAudioStreamType(AudioManager.STREAM_ALARM);
player.setLooping(true);
player.prepare();
float alarmVolume = AudioUtils.getMediaPlayerScaledVolume(100, alarm.volume);
if(NetworkUtils.isInCall(context)) {
alarmVolume = IN_CALL_VOLUME;
}
mediaPlayer.setVolume(alarmVolume, alarmVolume); //I've even tried hardcoding 0.1f
No matter what I do, it seems like the value I put in MediaPlayer.setVolume gets ignored, and the volume of the stream (in this case the alarm stream) gets used instead. It's most noticeable when the stream volume is set to max, and I play two audio files, one with MediaPlayer.setVolume(1f, 1f) and the other with MediaPlayer.setVolume(0.01f, 0.01f). They are almost indistinguishable from one another. I need a way for my users to be able to position the SeekBar at 1 and get a barely audible sound, or at 100 and have the max sound. Is this possible or am I gonna have to go back to messing with streams?
Set volume:
it will set maximum value(100) to Alarm Stream.
amanager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
amanager.setStreamVolume(AudioManager.STREAM_ALARM, amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM), AudioManager.FLAG_PLAY_SOUND);
Can it be you have two objects "player" and "mediaPlayer"? Here I just used that API, and it works as was to be expected.

Controlling the volume of forced-to-speaker audio

I'm playing an audio clip using OpenSL ES. In my code I have
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
to force audio through the speaker while the headset is plugged in. It works fine, but I can't control the volume. Pressing the volume buttons while the clip is playing makes the volume seekbar appear and move, but the volume doesn't change.
Calling setVolumeControlStream(AudioManager.STREAM_VOICE_CALL) or setVolumeControlStream(AudioManager.STREAM_MUSIC) before playing doesn't seem to help.
Changing any of the volumes outside of my app (e.g. in the Android settings) doesn't affect the playing volume. Volume control works well on both headset and speaker when no routing is applied.
I've also tried routing the audio to the speaker using this code I found in another answer
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
but it doesn't work on my Android 4.3 Nexus 4. I need the most compatible way to to that anyway.
Any ideas?
Thanks.
Here is a couple ideas:
MODE_IN_CALL sets all sorts of priority/policy on STREAM_VOICE_CALL. During this time, other STREAM may loose volume control focus. See if your audio clip is played over STREAM_VOICE_CALL.
MODE_IN_COMMUNICATION (for VoIP) may be a better fit for you. MODE_IN_CALL is for cellular call and can degrade your audio quality.
You may want to try grab audio focus and see if that helps. http://developer.android.com/training/managing-audio/audio-focus.html

Changing volume for one alarm sound only on Android

I am working on a life saving medical app and if the user is in a life threatening situation, they need to hear the alert.
When I have a notification to the status bar or have a dialog appear for a critical message to the user, I need to get their attention. If the media volume or ringer volume is low or off, I want to override it for my alert only. I would prefer not to change the settings for the phone, just for my one sound that I want to play.
When I try:
AudioManager audioManager = (AudioManager)getSystemService(this.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_RING,
audioManager.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
This correctly sets the volume for my stream but has the side effect of changing the stream volume for everyone else.
Is there a way of setting the volume for one song only?
It could be set back after the song is done.
AudioManager audioManager = (AudioManager)getSystemService(this.AUDIO_SERVICE);
int current_volume=audioManager.getStreamVolume(AudioManager.STREAM_RING);
audioManager.setStreamVolume(AudioManager.STREAM_RING,
audioManager.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
// Play here
audioManager.setStreamVolum(AudioManager.STREAM_RING,current_volume,0);

Override silent mode and/or media volume

I want to override the silent mode and/or media volume to make the phone broadcast a loud noise. I know the alarm clock can override silent mode. How do you do this through your app?
Are you asking whether the Alarm Clock app can override silent mode or if code can override silent mode?
The code answer is yes, you can change the silent mode setting via code like this:
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
int currentVolume = audio.getStreamVolume(AudioManager.STREAM_RING);
int max = audio.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION);
audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audio.setStreamVolume(AudioManager.STREAM_RING, max, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
I got another way, as the Tony's answer was worked but what happen it will change the profile suppose you put your device into the silent mode and app required to play any sound like alarm tone then it will change your profile silent to ringer mode and then again you need to put into silent mode. Am I right?
So the another solution was you can play the ringtone here snippet given below
int volume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
if(volume==0)
volume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, volume,AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
ringtone = RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(ringTonePath));
if(ringtone!=null){
ringtone.setStreamType(AudioManager.STREAM_ALARM);
ringtone.play();
isRinging = true;
}
isRinging set as flag if you want to programatically stop the playing or you can check the by isPlaying() of ringtone to stop playing
going through this I didn't change the current profile and no more code for that
Prey is an open source phone tracker app which does this as one if its features - if you don't get a better answer could have a look at the source to see how they did it.

Categories

Resources