【问题标题】:How to shut off the sound MediaRecorder plays when the state changes状态改变时如何关闭MediaRecorder播放的声音
【发布时间】:2011-07-24 00:30:38
【问题描述】:

我的 Android 应用程序使用 SurfaceHolder 上的 MediaRecorder 来显示相机正在捕捉的内容的实时预览。每次用户按下应用程序上的 REC 按钮时,应用程序就会开始录制。 每次 MediaRecorder 的状态切换到“开始”/从“开始”切换时,Android 都会自动 (?) 发出哔声。这个哔声在不同的手机上听起来不同,这让我觉得这个哔声是原生附加到 MediaRecorder 的状态变化的。 如果手机音量设置为静音,则不会发出提示音。

我用谷歌搜索并做了一些研究,但我找不到关闭此哔声的方法。可能吗?如果有,怎么做?

该应用已在:Nexus One 2.3.4、Desire HD 2.3.3 上测试

【问题讨论】:

    标签: android audio media record


    【解决方案1】:

    好的,接受的答案对我不起作用。在通过 MediaRecorder 录制时,在运行 4.2.1 (Jelly Bean) 的 Galaxy Nexus 上,我需要使用 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);
    

    正如documentation 所指出的,请务必在onPause() 方法中重新启用音频。

    我希望这可以帮助那些为这个问题而烦恼的人。这将禁用所有声音流。您可以查看并确定您特别需要哪些。我发现当 mediarecorder 运行时,不同版本的 android 使用不同的流作为铃声。即,STREAM_RING 适用于 android 4.2.1 但不适用于 ICS。

    编辑:正如我在下面的评论中提到的,我无法在三星 Galaxy S1 上禁用 Android OS 2.3.3 的声音。有谁有这方面的运气吗?

    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_ 行。但现在对我来说,这些结合起来是有效的。希望这对某人有所帮助...

    【讨论】:

    • 感谢此代码。使用的流因设备而异,非常有用。我发现接受的解决方案适用于 HTC Desire,但不适用于 Nexus 4。您的代码适用于两者。
    • @darrenp 很高兴您发现这是一个解决方案。我实际上找不到任何适用于运行 2.3.3 的三星 Galaxy S1 的解决方案。我尝试过的所有其他操作似乎都禁用了声音
    • 嗯,这几乎是 100% 的解决方案!请参阅我上面关于使用我建议的反射方法的评论。让我知道你过得怎么样。
    【解决方案2】:

    试试

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

    静音所有声音。

    【讨论】:

    • 是的,我做过类似的事情。不过,这不是理想的解决方案。目前,这似乎是唯一的解决方案。
    • 此解决方案不适用于在 Galaxy Nexus 上使用 Android 4.2.1 的我。任何人都可以在通过MediaRecorder 使用最新版本的android 录制时禁用哔声?
    • 我终于找到了解决办法...在下面发帖
    • java.lang.SecurityException: 不允许更改请勿打扰状态
    【解决方案3】:

    根据@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。我猜/希望将这些静音也没有害处!

    【讨论】:

    • @darrrenp 谢谢我现在使用你的 setMuteAll() 方法很好。但是,我仍然无法在运行 Android 2.3.3 的三星 Galaxy S1 上禁用声音。不知道为什么。该代码在我测试过的其他设备上运行良好。您在运行 2.3.3 的手机上遇到过问题吗?基本上每次 MediaRecorder 开始录制视频时它都会发出哔哔声,然后在停止时再次发出哔哔声。
    • @wired00 很高兴它很有用。感谢您的原始帖子!我还没有用 S1 试过这个。您是否尝试过反射方法?这不仅会静音setMuteAll() 中数组中的静音。不幸的是,我没有任何 2.3.3 设备。
    • 我不使用静音,因为据报道在某些情况下它会被忽略,但我确实发现我获取和设置音量的反射方法存在问题。它找到了这个流: (STREAM_INCALL_MUSIC(10)),它在 MotoG 上尝试获取音量时抛出了错误。来自 getStreamVolume 的“java.lang.IllegalArgumentException:错误的流类型 10”。
    • @LanceNanek 知道有用。谢谢。我想我们总是可以捕捉到这样的异常并将其与反射方法(或任何其他建议的方法)结合起来。然而,虽然更整洁,但使用反射远非良好的 OOP。 TBH,我不知道为什么像关闭声音这样简单的任务在 Android 上如此复杂!
    【解决方案4】:

    我刚刚在运行 Android 4.2.1 的 Lenovo K900 上遇到了这个问题。 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);
    

    【讨论】:

    • 传奇。这绝对对我有用。在我的手机(Galaxy Nexus)Android 4.3 最新更新之前,我的上述解决方案和 darrenp 的解决方案一直对我有用。录音的哔哔声突然又响了起来。这解决了它。
    • 是的!这在我的 Galaxy S2 中就像一个魅力。谢谢!
    【解决方案5】:

    在开始前添加这段代码:

    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。也有一些国家认为这是非法的,但使用不同的渠道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多