Android 如何在状态改变时关闭录音机播放

Android 如何在状态改变时关闭录音机播放,android,audio,media,record,Android,Audio,Media,Record,我的Android应用程序在SurfaceHolder上使用MediaRecorder来实时预览相机拍摄的内容。每次用户按下应用程序上的REC按钮,应用程序就会开始录制。 每次MediaRecorder的状态切换到“开始”或从“开始”切换到“开始”,Android都会自动(?)发出一声蜂鸣音。这种蜂鸣音在不同的电话中听起来不同,这让我觉得这种蜂鸣音是与MediaRecorder的状态变化相关的。 如果手机音量设置为静音,则不会播放蜂鸣音 我在谷歌上搜索了一下,做了一些研究,但是我找不到一个方法来

我的Android应用程序在SurfaceHolder上使用MediaRecorder来实时预览相机拍摄的内容。每次用户按下应用程序上的REC按钮,应用程序就会开始录制。 每次MediaRecorder的状态切换到“开始”或从“开始”切换到“开始”,Android都会自动(?)发出一声蜂鸣音。这种蜂鸣音在不同的电话中听起来不同,这让我觉得这种蜂鸣音是与MediaRecorder的状态变化相关的。 如果手机音量设置为静音,则不会播放蜂鸣音

我在谷歌上搜索了一下,做了一些研究,但是我找不到一个方法来关闭这个嘟嘟声。可能吗?如果是,怎么做

该应用程序在以下平台上进行了测试:NexusOne2.3.4,Desire HD 2.3.3

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

使所有声音静音

在开始之前添加此代码:

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_系统,有些则使用STREAM_音乐。在某些国家,这是非法的,但使用不同的频道。

好的,接受的答案对我不起作用。在运行4.2.1(Jelly Bean)的Galaxy Nexus上,当通过MediaRecorder录制时,我需要使用
AudioManager.STREAM\u RING
,因为
AudioManager.STREAM\u系统不起作用。每次录音开始时,它都会播放“蜂鸣”音

下面是我使用“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()
方法中重新启用音频

我希望这能帮助人们解决这个问题。这将禁用所有声音流。你可以仔细研究,找出你特别需要的。我发现当mediarecorder运行时,不同版本的android使用不同的流作为提示。也就是说,STREAM_环适用于android 4.2.1,但对于ICS则不起作用

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

Darrenp的解决方案有助于整理代码,但在我的手机(galaxy nexus android 4.3)的最新更新中,音量/录音蜂鸣再次响起!用户1944526的解决方案肯定会有所帮助。为了使它更容易理解

比如说

// 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的解决方案,或者包含上述所有
行。但现在对我来说,这些结合在一起是有效的。希望这对某人有所帮助…

根据@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);
}
目前这种方法还可以,但如果将来引入更多的流,则此方法可能需要更新。一种更可靠的方法(尽管可能有些过分)是使用反射来获取所有流静态字段:

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
        }
    }
}
List streams=new ArrayList();
Field[]fields=AudioManager.class.getFields();
用于(字段:字段){
if(field.getName().startsWith(“STREAM”)
&&Modifier.isStatic(field.getModifiers())
&&field.getType()==int.class){
试一试{
整数流=(整数)字段.get(null);
流。添加(流);
}捕获(IllegalArgumentException e){
//无所事事
}捕获(非法访问例外e){
//无所事事
}
}
}

有趣的是,似乎有一些流没有被记录,即STREAM_BLUETOOTH_SCO、STREAM_SYSTEM_强制和STREAM_TTS。我猜/希望把这些也静音也没有害处

我刚刚在运行安卓4.2.1的联想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.2.1。有人能在使用最新版本的android通过MediaRecorder录制时禁用蜂鸣音吗?我终于找到了解决方案。。。发布在下面java.lang.SecurityException:不允许更改请勿打扰状态感谢您的代码。非常有用的是,所使用的流因设备而异。我发现被接受的解决方案适用于HTC,但不适用于Nexus4。您的代码对这两个方面都有效。@darrenp我很高兴您找到了解决方案。我实际上找不到任何适用于运行2.3.3的三星Galaxy S1的解决方案。它似乎禁用了声音的一切,我试过,但这几乎是一个100%的解决方案!请参阅我上面关于使用我建议的反射方法的评论。让我知道你的进展情况。@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:Bad stream type 10”。@LanceNanek了解这一点很有用。谢谢我想我们总是可以捕捉到这样的异常,并将其与反射方法(或任何其他建议的方法)结合起来。然而,尽管更整洁,但使用反射远远不是好的OOP。TBH,我不知道为什么在Android上关闭声音这样简单的任务如此复杂!传奇这对我来说也确实有效。我的上述解决方案和