10

I implement a RecognitionListener inside of a tabbed fragment activity. What happens is that as the user scrolls around, the fragment that implements the listener is created/destroyed and on my Nexus 7 and Galaxy Nexus you hear a sound associated to the RegonitionListener, or maybe its the SpeechRecognizer, being ready for use. Whichever class is the cause of the sound, I would like to allow the user to disable it. I realize currently my issue is that I am listening without the users focus which I am resolving; however, I still do not want to hear the sound by default and prefer to let the user opt into the notification sound.

So my question is this, is it possible to disable the notification sound associated to the listener? I have been unable to find this in the docs.

ian.shaun.thomas
  • 3,468
  • 25
  • 40
  • 2
    I guess that sound is generated by the speech recognition service, which means it unlikely that your app can change that especially since I don't see any options for that sound in the system settings or the official voice search popup. You could try muting the volume during speech recognition but that would also mute any background music that could be ongoing. – zapl Aug 14 '12 at 12:12
  • Background music gets cut anyways when the recognition listener is started. I would prefer to avoid using a hack if possible though. Props for the idea! – ian.shaun.thomas Aug 14 '12 at 12:18

3 Answers3

17

As zapl said that there is no direct method to do that but you can try muting the system volume and as you, Tencent said that you are avoiding any kind of hack. Then I must say there is no method SO FAR to do this, But still I'm sharing this trick solution for those who are suffering from same issue and may not mind a "hack" trick. Just saving their hours of frustration.

Mute the system volume for that particular time then un-mute after. How to do this:

In your class, create following objects

private AudioManager mAudioManager;
private int mStreamVolume = 0; 

In your onCreate method do following.

mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

When you start listening for Speech Recognition, do following

speechRecognizer.startListening(intent); // this method make that annoying sound
mStreamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // getting system volume into var for later un-muting 
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0); // setting system volume to zero, muting

In your Speech RecognitionListener interface there should be a method onReadyForSpeech.

class MyRecognitionListener implements RecognitionListener          
{
  public void onReadyForSpeech(Bundle params)
  {
    // this methods called when Speech Recognition is ready
    // also this is the right time to un-mute system volume because the annoying sound played already
    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mStreamVolume, 0); // again setting the system volume back to the original, un-mutting
  }
}

This is how you can play a trick with this annoying sound. Obviously any other sound will also be mute for a second.

Bilal Rabbani
  • 1,288
  • 14
  • 24
  • 2
    I reset the volumn in function `public void onResults(Bundle results)`. Because there is another sound after the speech recognition. – William Aug 25 '15 at 16:00
4

Previous answer is OK except it will crash because of a NullPointer Exception (getStreamVolume is being called on a null object). To fix that, before the getStreamVolume line add:

AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

Abandoned Cart
  • 4,512
  • 1
  • 34
  • 41
dalvallana
  • 469
  • 6
  • 13
1

If you want to stop the end sound as well, you can unmute the sound in onResults and onError instead of onReadyForSpeech.

Create a handler as a member variable:

private Handler mHandler = new Handler();

The RecognitionListener methods:

@Override
public void onResults(Bundle results) {
    // Your logic here
    startAudioSound();
}

@Override
public void onError(int errorCode) {
    // Your logic here
    startAudioSound();
}

private void startAudioSound(long delay) {
    mHandler.postDelayed(() -> {
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mStreamVolume, 0); // again setting the system volume back to the original, un-mutting
    }, 300);
}

I've tested with a 300 millisecond delay and it works. Shorter delays may also work.

Vlad
  • 988
  • 12
  • 18
  • 2 things: 1) I did it in `onResults` and it worked fine. 2)I used `SystemClock.sleep(300);` instead of `Handler.postDelayed` [source for 1]: https://stackoverflow.com/questions/11951723/disable-ready-sound-of-recognition-listener#comment52301512_21935042 [source for 2]: https://stackoverflow.com/a/14615606/13093413 – Trake Vital Jul 06 '20 at 13:44