Как отключить воспроизведение звука MediaRecorder при изменении состояния

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

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

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

5 ответов


попробовать

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

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


Ok принятый ответ не работал для меня. На 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 используют разные потоки для перезвона при запуске mediarecorder. т. е. STREAM_RING работает для android 4.2.1, но для ICS он не работает.

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

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

}

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


после ответа @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. Я угадывание / надеясь, что нет никакого вреда в приглушении их тоже!


У меня просто была эта проблема на 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);

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

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. Есть также страны, где это незаконно, но используют другой канал.