How to shut off the sound MediaRecorder plays when the state changes

9

11

My Android application uses MediaRecorder on a SurfaceHolder to show a live preview of what the camera is capturing. Every time the user presses the REC button on the app, the app starts to record. Every time the state of the MediaRecorder switches to/from 'start', Android automatically (?) fires off a beep. This beep sounds different from phone to phone, which makes me think that this beep is natively attached to the state change of MediaRecorder. The beep is not played if the volume of the phone is set to silent.

I google it and did some research but I couldn't find a way to turn this beep off. Is it possible? If so, how?

The app was tested on: Nexus One 2.3.4, Desire HD 2.3.3

Rafael Ramos

Posted 2011-07-24T00:30:38.223

Reputation: 95

Answers

4

try

((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);

That mute all sounds.

esse

Posted 2011-07-24T00:30:38.223

Reputation: 249

this solution doesn't work for me using Android 4.2.1 on a Galaxy Nexus. Anyone able to get the beep disabled when recording via MediaRecorder with a late version of android? – wired00 – 2012-12-05T01:17:46.757

Finally i found the solution... posting below – wired00 – 2012-12-07T05:48:34.123

Doesn't work for me too... – TheOnlyAnil – 2015-07-01T10:21:48.130

Yeah, I did something like that. Not the ideal solution, though. For now, it seems to be the only solution. – Rafael Ramos – 2011-08-03T09:50:11.930

java.lang.SecurityException: Not allowed to change Do Not Disturb state – Ajay Shrestha – 2018-03-28T00:56:31.447

7

Ok the accepted answer did not work for me. On a Galaxy Nexus Running 4.2.1 (Jelly Bean) when recording via MediaRecorder I needed to use AudioManager.STREAM_RING because AudiManager.STREAM_SYSTEM did not work. It would always play a "chime" sound at beginning of each recording.

Here is my solution using "STREAM_RING" and others.

// disable sound when recording.
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_ALARM,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_DTMF,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_MUSIC,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_RING,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_VOICE_CALL,true);

// re-enable sound after recording.
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_ALARM,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_DTMF,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_MUSIC,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_RING,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_VOICE_CALL,false);

Also as the documentation states be sure to re-enable audio in the onPause() method.

I hope this helps someone tearing their hair out over this problem. This disables all sound streams. You can go through and work out which ones you specifically need. I found that different versions of android use different streams for the chime when mediarecorder runs. ie, STREAM_RING works for android 4.2.1 but for ICS it doesn't work.

Edit: As my comment below mentions, I can't get the sound disabled for Android OS 2.3.3 on a Samsung Galaxy S1. Anyone have luck with this?

Darrenp's solution helps to tidy up code but in a recent update to my phone (galaxy nexus android 4.3) the volume / recording beep started up again! The solution by user1944526 definitely helps. In an effort to make it easier to understand...

Use something like ,

// class variables.
Integer oldStreamVolume;
AudioManager audioMgr;


enableSound() {
        setMuteAll(false);
        if (audioMgr != null && oldStreamVolume != null) {
            audioMgr.setStreamVolume(AudioManager.STREAM_RING, oldStreamVolume, 0); 
        }
}

disableSound() {
        audioMgr = (AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        oldStreamVolume = audioMgr.getStreamVolume(AudioManager.STREAM_RING);
        audioMgr.setStreamVolume(AudioManager.STREAM_RING, 0, 0);       

}

For completeness each of those functions you could also call either darrenp's solution in a function or include all of the above STREAM_ lines. but for me now, these combined are working. Hope this helps someone...

wired00

Posted 2011-07-24T00:30:38.223

Reputation: 8 491

Thanks for this code. Very useful that the stream used varies across devices. I found the accepted solution worked for an HTC Desire but not for a Nexus 4. Your code works for both. – darrenp – 2013-02-20T11:35:05.193

@darrenp I'm glad you found this as a solution. I actually can't find any solution which works for Samsung Galaxy S1 running 2.3.3. It seems to disable sound for everything else i tried though – wired00 – 2013-02-21T00:44:59.440

Well it's almost a 100% solution! See my comment above about using the reflection approach I suggested. Let me know how you get on. – darrenp – 2013-03-06T12:32:44.610

1Doesn't work for mediarecorder.start/stop sound. – TheOnlyAnil – 2015-07-01T10:22:28.823

4

Following on from @wired00's answer, the code can be simplified as follows:

private void setMuteAll(boolean mute) {
    AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

    int[] streams = new int[] { AudioManager.STREAM_ALARM,
        AudioManager.STREAM_DTMF, AudioManager.STREAM_MUSIC,
        AudioManager.STREAM_RING, AudioManager.STREAM_SYSTEM,
        AudioManager.STREAM_VOICE_CALL };

    for (int stream : streams)
        manager.setStreamMute(stream, mute);
}

This works fine for now but if more streams are introduced in the future, this method may need updating. A more robust approach (though perhaps overkill) is to use reflection to get all the STREAM_* static fields:

List<Integer> streams = new ArrayList<Integer>();
Field[] fields = AudioManager.class.getFields();
for (Field field : fields) {
     if (field.getName().startsWith("STREAM_")
         && Modifier.isStatic(field.getModifiers())
         && field.getType() == int.class) {
         try {
             Integer stream = (Integer) field.get(null);
             streams.add(stream);
         } catch (IllegalArgumentException e) {
              // do nothing
         } catch (IllegalAccessException e) {
             // do nothing
        }
    }
}

Interestingly, there seem to be some streams that are not documented, namely STREAM_BLUETOOTH_SCO, STREAM_SYSTEM_ENFORCED and STREAM_TTS. I'm guessing/hoping there's no harm in muting these too!

darrenp

Posted 2011-07-24T00:30:38.223

Reputation: 3 182

@darrrenp Thanks I'm now using your setMuteAll() method its nice. However, I've continued to be unable to disable sound on a Samsung Galaxy S1 running Android 2.3.3. Not sure why. The code works fine on other devices I've tested. Have you experienced issues on phones running 2.3.3? basically each time the MediaRecorder starts recording video it beeps, then again when it stops. – wired00 – 2013-03-06T06:03:44.870

@wired00 Pleased it's useful. Thanks for your original post! I haven't tried this with an S1. Have you tried the reflection approach? This mutes more than just the ones in the array in setMuteAll(). I don't have any 2.3.3 devices unfortunately. – darrenp – 2013-03-06T12:30:10.350

this doesn't work for me – suitianshi – 2014-12-16T05:02:49.277

1I don't use mute since that is reportedly ignored in some cases, but I did find an issue with the reflection approach where i get and set the volumes. It found this stream: (STREAM_INCALL_MUSIC(10)) which on the MotoG threw an error when trying to get the volume. "java.lang.IllegalArgumentException: Bad stream type 10" from getStreamVolume. – Lance Nanek – 2015-03-17T16:29:01.060

@LanceNanek Useful to know. Thanks. I guess we could always catch such exceptions and combine it with the reflection approach (or any other approach proposed). However, although neater, using reflection is far from good OOP. TBH, I have no idea why a task as simple as turning off a sound is so complex on Android! – darrenp – 2015-03-18T17:33:20.597

2

I just had this problem on a Lenovo K900 running Android 4.2.1. setStreamMute doesn't seem to do anything for me, but setStreamVolume works...

AudioManager audioMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int oldStreamVolume = audioMgr.getStreamVolume(AudioManager.STREAM_RING);
audioMgr.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
... do recording ...
audioMgr.setStreamVolume(AudioManager.STREAM_RING, oldStreamVolume, 0);

user1944526

Posted 2011-07-24T00:30:38.223

Reputation: 26

1Legend. this definitely worked for me too. My above solution and darrenp's solutions were working for me until the latest update to my phone (Galaxy Nexus) Android 4.3. The recording beep suddenly started up again. This fixed it. – wired00 – 2013-10-25T11:47:08.213

Yes! This worked like a charm in my Galaxy S2. Thanks! – Federico Cristina – 2015-01-05T00:23:35.770

Sorry but even this didn't work for me :/ – TheOnlyAnil – 2015-07-01T10:27:23.083

1

Add this code before the start:

AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);

audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC,true);

And add this code after the stop:

AudioManager audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);

audioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC,false);

There are countries/firmwares that use STREAM_SYSTEM and others using STREAM_MUSIC. There are also countries where this is illegal but use a different channel.

JMPergar

Posted 2011-07-24T00:30:38.223

Reputation: 1 456