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

前端 未结 5 1752
自闭症患者
自闭症患者 2020-12-23 23:20

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, t

相关标签:
5条回答
  • 2020-12-24 00:02

    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);
    
    0 讨论(0)
  • 2020-12-24 00:04

    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!

    0 讨论(0)
  • 2020-12-24 00:10

    try

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

    That mute all sounds.

    0 讨论(0)
  • 2020-12-24 00:15

    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...

    0 讨论(0)
  • 2020-12-24 00:16

    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.

    0 讨论(0)
提交回复
热议问题