Jak wyłączyć odtwarzanie sound MediaRecorder po zmianie stanu

Moja aplikacja na Androida używa MediaRecorder na elemencie powierzchniowym, aby pokazać podgląd na żywo tego, co kamera przechwytuje. Za każdym razem, gdy użytkownik naciska przycisk REC w aplikacji, aplikacja zaczyna nagrywać. Za każdym razem, gdy stan MediaRecorder przełącza się do / Z "start", Android automatycznie (?) odpala sygnał dźwiękowy. Ten sygnał dźwiękowy brzmi inaczej w zależności od telefonu, co sprawia, że myślę, że ten sygnał jest natywnie związany ze zmianą stanu MediaRecorder. Sygnał dźwiękowy nie jest odtwarzany, jeśli głośność telefon jest ustawiony na cichy.

Wygooglowałem to i trochę poszperałem, ale nie mogłem znaleźć sposobu, aby wyłączyć ten sygnał. Czy to możliwe? Jeśli tak, to w jaki sposób?

Aplikacja była testowana na: Nexus One 2.3.4, Desire HD 2.3.3

Author: Rafael Ramos, 2011-07-24

5 answers

Try

((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);
To wycisza wszystkie dźwięki.
 4
Author: esse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 22:46:07

Ok przyjęta odpowiedź nie zadziałała dla mnie. Na Galaxy Nexusie z 4.2.1 (Jelly Bean) podczas nagrywania przez MediaRecorder musiałem użyć AudioManager.STREAM_RING, ponieważ AudiManager.STREAM_SYSTEM nie działało. Na początku każdego nagrania zawsze odtwarzał dźwięk "dzwonka".

Oto moje rozwiązanie przy użyciu "STREAM_RING" i innych.

// 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);

Również zgodnie z dokumentacją należy ponownie włączyć dźwięk w metodzie onPause().

Mam nadzieję, że to pomoże komuś oderwać włosy od tego problem. To wyłącza wszystkie strumienie dźwiękowe. Możesz przejść i ustalić, których konkretnie potrzebujesz. Zauważyłem, że różne wersje Androida używają różnych strumieni do dzwonka, gdy działa mediarecorder. ie, STREAM_RING działa dla Androida 4.2.1, ale dla ICS nie działa.

Edit: jak mój komentarz poniżej wspomina, nie mogę uzyskać dźwięk wyłączony dla Android OS 2.3.3 na Samsung Galaxy S1. Ktoś ma z tym szczęście?

Rozwiązanie Darrenpa pomaga uporządkować kod, ale w ostatnia aktualizacja mojego telefonu (galaxy nexus android 4.3) dźwięk głośności / nagrywania zaczął się ponownie! Rozwiązanie przez user1944526 zdecydowanie pomaga. W celu ułatwienia zrozumienia...

Użyj czegoś w rodzaju,

// 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);       

}

Dla kompletności każdej z tych funkcji można również wywołać rozwiązanie darrenpa w funkcji lub dołączyć wszystkie powyższe linie STREAM_. ale dla mnie teraz, te połączone działają. Mam nadzieję, że to komuś pomoże...

 7
Author: wired00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 11:55:29

Po odpowiedzi @wired00, kod można uprościć w następujący sposób:

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);
}

Na razie działa to dobrze, ale jeśli w przyszłości wprowadzi się więcej strumieni, ta metoda może wymagać aktualizacji. Bardziej solidnym podejściem (choć być może przesadą) jest użycie reflection, aby uzyskać wszystkie statyczne pola STREAM_*:

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

Co ciekawe, wydaje się, że istnieją pewne strumienie, które nie są udokumentowane, a mianowicie STREAM_BLUETOOTH_SCO, STREAM_SYSTEM_ENFORCED i STREAM_TTS. Zgaduję / mam nadzieję, że jest nie zaszkodzi wyciszyć te też!

 4
Author: darrenp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-09 04:11:05

Właśnie miałem ten problem na Lenovo K900 z Androidem 4.2.1. setStreamMute nic dla mnie nie robi, ale setStreamVolume działa...

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);
 2
Author: user1944526,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-30 22:59:15

Dodaj ten kod przed rozpoczęciem:

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

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

I dodać ten kod Po zatrzymaniu:

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

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

Istnieją kraje / oprogramowanie firmowe, które używają STREAM_SYSTEM i inne używają STREAM_MUSIC. Są też kraje, w których jest to nielegalne, ale korzystają z innego kanału.

 1
Author: JMPergar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-06 14:58:30