Как отключить звук, который проигрывает MediaRecorder при изменении состояния - PullRequest
11 голосов
/ 24 июля 2011

Мое приложение Android использует MediaRecorder на SurfaceHolder, чтобы показать предварительный просмотр того, что захватывает камера.Каждый раз, когда пользователь нажимает кнопку «REC» в приложении, приложение начинает запись.Каждый раз, когда состояние MediaRecorder переключается в режим «пуск», Android автоматически (?) Отключает звуковой сигнал.Этот звуковой сигнал отличается от телефона к телефону, что заставляет меня думать, что этот звуковой сигнал изначально связан с изменением состояния MediaRecorder.Звуковой сигнал не воспроизводится, если громкость телефона установлена ​​на бесшумный режим.

Я запустил Google и провёл некоторые исследования, но не смог найти способ отключить этот звуковой сигнал.Является ли это возможным?Если да, то как?

Приложение было протестировано на: Nexus One 2.3.4, Desire HD 2.3.3

Ответы [ 5 ]

7 голосов
/ 07 декабря 2012

Хорошо, принятый ответ не работает для меня.На Galaxy Nexus под управлением 4.2.1 (Jelly Bean) при записи через MediaRecorder мне нужно было использовать AudioManager.STREAM_RING, потому что AudiManager.STREAM_SYSTEM не работал.Он всегда будет воспроизводить звук «колокольчика» в начале каждой записи.

Вот мое решение с использованием "STREAM_RING" и других.

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

Также в качестве документации состояния обязательно повторно включите звук в методе onPause().

Надеюсь, это поможет кому-то вырвать волосы из-за этой проблемы.Это отключает все звуковые потоки.Вы можете пройти и выяснить, какие именно вам нужны.Я обнаружил, что разные версии Android используют разные потоки для звонка при запуске медиа-рекордер.то есть STREAM_RING работает для Android 4.2.1, но для ICS не работает.

Редактировать: Как упоминается в моем комментарии ниже, я не могу отключить звук для Android OS 2.3.3 на Samsung GalaxyS1.Кому-нибудь повезло с этим?

Решение Darrenp помогает привести в порядок код, но в недавнем обновлении моего телефона (galaxy nexus android 4.3) снова прозвучал сигнал громкости / записи!Решение пользователя user1944526 определенно помогает.Чтобы облегчить понимание ...

Используйте что-то вроде

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

}

Для полноты каждой из этих функций вы также можете вызвать решение Дарренпа в функции или включить всеиз вышеуказанных STREAM_ строк.но для меня сейчас эти вместе работают.Надеюсь, это кому-нибудь поможет ...

5 голосов
/ 03 августа 2011

попробуй

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

Это отключает все звуки.

4 голосов
/ 20 февраля 2013

Исходя из ответа @ wired00, код можно упростить следующим образом:

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

Пока это работает нормально, но если в будущем будет введено больше потоков, этот метод может потребовать обновления.Более надежный подход (хотя, возможно, и избыточный) заключается в использовании отражения для получения всех статических полей 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
        }
    }
}

Интересно, что некоторые потоки не документированы, а именно STREAM_BLUETOOTH_SCO, STREAM_SYSTEM_ENFORCED и STREAM_TTS,Я предполагаю / надеюсь, что приглушить их тоже не повредит!

2 голосов
/ 31 июля 2013

У меня только что была эта проблема на Lenovo K900 под управлением Android 4.2.1. setStreamMute, кажется, ничего не делает для меня, но setStreamVolume работает ...

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);
1 голос
/ 06 марта 2012

Добавьте этот код перед началом:

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

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

И добавить этот код после остановки:

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

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

Есть страны / прошивки, в которых используется STREAM_SYSTEM, а в других - STREAM_MUSIC. Есть также страны, где это незаконно, но используют другой канал.

...