3

I've been looking through different threads and haven't found anything that has worked for me on the problem that I am experiencing. I'd like to get rid of the "beep" sound that you get when speech recognition starts. I'm working with Jelly Bean 4.2.2 so I'm not sure if the same problem is on early versions, if it is I'd also like a fix for that. Also, I was wondering if anyone has suggestions on how to respond to certain Speech Recognition Results. Please let me know how my code can be improvised to include those features.

package com.example.speech;

import java.util.ArrayList;

import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Activity;
import android.content.Intent;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.view.Menu;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.util.Log;

public class MainActivity extends Activity implements  OnClickListener {



ListView lv;
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent; 
boolean reseter = false;
private AudioManager mAudioManager;
private volatile boolean mNoSpeechCountDownOn;


@Override
protected void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    boolean available = SpeechRecognizer.isRecognitionAvailable(this);
    Log.d("Speech", "available = " + available);
    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    mSpeechRecognizer.setRecognitionListener(new SpeechListener());
    mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
            this.getPackageName());
    mAudioManager = (AudioManager) getSystemService(this.AUDIO_SERVICE);
    commandA();



}

private CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{   
    @Override
    public void onTick(long millisUntilFinished)
    {

    }

    @SuppressWarnings("synthetic-access")
    @Override
    public void onFinish()
    {
        mNoSpeechCountDownOn = false;
        mSpeechRecognizer.cancel();
        mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
    }
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}


private class SpeechListener implements RecognitionListener {


    @Override
    public void onBeginningOfSpeech() {
        if (mNoSpeechCountDownOn)
        {
            mNoSpeechCountDownOn = false;
            mNoSpeechCountDown.cancel();
        }
        Log.d("Speech", "onBeginningOfSpeech");

    }

    @Override
    public void onBufferReceived(byte[] buffer) {
        Log.d("Speech", "onBufferReceived");
    }

    @Override
    public void onEndOfSpeech() {
        Log.d("Speech", "onEndOfSpeech");


    }

    @Override
    public void onError(int error) {
        if (mNoSpeechCountDownOn)
        {
            mNoSpeechCountDownOn = false;
            mNoSpeechCountDown.cancel();
        }
        Log.d("Speech", "onError");
    }

    @Override
    public void onEvent(int eventType, Bundle params) {
        Log.d("Speech", "onEvent");
    }

    @Override
    public void onPartialResults(Bundle partialResults) {
        Log.d("Speech", "onPartialResults");
    }

    @Override
    public void onReadyForSpeech(Bundle params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            mNoSpeechCountDownOn = true;
            mNoSpeechCountDown.start();
            mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
        }
        Log.d("Speech", "onReadyForSpeech");
        try {
            Thread.sleep(4900);

        } catch (InterruptedException e) {
            mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
            mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
            Log.d("speech", "Mute on");

        }

    }


    @Override
    public void onResults(Bundle results) {
        Log.d("Speech", "results");


        ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

        // Do whatever you want here
        try {
            Thread.sleep(1);

        } catch (InterruptedException e) {
            mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
            mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
            Log.d("speech", "Mute on");

        }
    }

    @Override
    public void onRmsChanged(float rmsdB) {
        //Log.d("Speech", "onRmsChanged");
    }



}
@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

}
 }
Nitan Shalom
  • 69
  • 1
  • 2
  • 7
  • Hi Hoan, I used what you gave me to put down these results (I have updated my question) I'm receiving multiple errors mostly under the runtime. I wasn't sure if I had to declare a boolean. If you don't mind looking it over that would be great! – Nitan Shalom May 04 '13 at 04:45
  • Pretty much the only problem is that mNOSpeechCountDownOn variable is not defined in the code you provided. What do you suggest I define it as? – Nitan Shalom May 04 '13 at 16:50
  • I am still receiving a strange error threadid=1: thread exiting with uncaught exception (group=0x41b07348) and this causes a Fatal Exception: main with the tag AndroidRuntime. What could this be? What is the fix? – Nitan Shalom May 04 '13 at 20:58
  • I removed all your threads why do you put it hack? – Hoan Nguyen May 04 '13 at 21:19
  • I haven't changed anything in the code it is identical to the edit of yours. Take a look through the code,the error comes when the button is pressed. – Nitan Shalom May 04 '13 at 21:37
  • You did take a look at my answer and compare to what you have above. In my onResults there is no thread – Hoan Nguyen May 04 '13 at 21:44
  • The onResults method is not what is causing the error. The Thread in the onResults was taken out and the same error happened. I used the thread to repeat the class. I have edited my code on my post to what I currently have. – Nitan Shalom May 04 '13 at 22:08
  • add to your manifest – Hoan Nguyen May 04 '13 at 22:21
  • I have added the permission doesn't seem like it made much of a difference (I'm sure it will in the long run). – Nitan Shalom May 05 '13 at 16:59
  • copy my answer and run again – Hoan Nguyen May 05 '13 at 17:55
  • Working great! I used the threads to keep the voice recognition ongoing. Do you suggest a different way of doing so? – Nitan Shalom May 05 '13 at 20:24
  • What is the button for then? – Hoan Nguyen May 05 '13 at 20:29
  • I'll ultimately have the speechlistener start around 3-4 seconds after the app starts up and then have it going throughout the app (continuous). Right now I would like to try it in different places so I like to use the button. Ultimately it will be continuous and respond to different things that are said. Right now I have the results in an ArrayList called matches. I understand that inorder to respond to different things that are said I would have to use an if statement and set something equal to "matches". That's the idea of the app. But right now the next step is continuous speech rec. – Nitan Shalom May 05 '13 at 20:38
  • Then you just called startListen when you done processing the result. – Hoan Nguyen May 05 '13 at 20:42
  • I need to use a thread or a timer on the "onReadyForSpeech" if the user does not speak for 4.9 seconds and then call the startListen correct? Also there is a problem a huge problem when calling startListen after results because then it just loops. Also, the beep sound comes up! How would you suggest getting both continuous speech and no "beep" sound. The first time when I press the button it works but if I call the class when the results come in it causes tons of problems (I did use it before with a thread and I got the continuous speech to work very nicely). What's your approach? – Nitan Shalom May 05 '13 at 21:09
  • When you call startListening you have to set the audio as in the button code. As I understand you cannot call startListening in a thread, but if it works for you then use it. – Hoan Nguyen May 05 '13 at 21:15
  • I know that speechListener works well in threads, but I'm not sure what to put inside of my button.... Ultimately as I have said, I'd like to have the action of speechListener and the mute audio (does the audio muter just mute the speech recognizer or the entire sound that comes from the app)... Bottom line is that if I can implement all of those actions in the oncreate, that would be must better. – Nitan Shalom May 06 '13 at 00:26
  • Well you just have to play around with the code and see what is best for you. I only use speech regconizer in service, so I do not what best for you in an activity. – Hoan Nguyen May 06 '13 at 00:33
  • Well, can you please show me what it looks like in a service? Ultimately I want the beep to be muted, and just the beep, I want there to be no pop up window, I want it to be ongoing(I think I know how to do that) and that's basically it, but does the way that you showed me to mute the beep mute the entire app? – Nitan Shalom May 06 '13 at 00:33
  • The mute only mute the system sound, you should be fine with the mute code. I haven't experience any problem with it. For service take a look at http://stackoverflow.com/questions/14940657/android-speech-recognition-as-a-service-on-android-4-1-4-2/14950616#14950616 – Hoan Nguyen May 06 '13 at 00:40
  • Ok, so what are the differences between an activity and service in this case, also if the results then trigger a sound, you are saying that it should not mute the the sound that is triggered by the class. Also, how do I implement the muter in my onCreate? Is that possible? Do you suggest I should switch my app to a service? – Nitan Shalom May 06 '13 at 00:44
  • onReadyForSpeech unmute the system sound so you should not have any problem with sound. A service does not need a UI. For example, in my almost complete app, you just say a name in your contact, and my app will place a phone call to that contact even when the screen is off. – Hoan Nguyen May 06 '13 at 00:50
  • Hmm... interesting, can you edit my code to show me how to unmute (still a beginner) in the onReadyForSpeech? – Nitan Shalom May 06 '13 at 00:53
  • It is already in your onReadyForSpeech code – Hoan Nguyen May 06 '13 at 00:56
  • Didn't notice that, right now I have my results put into an ArrayList. I want the app to respond to different words that are said, because I'll probably lose all of my reputation if I ask that question on this form, do you mind quickly answer it since you probably know the most of this type of stuff on this website? – Nitan Shalom May 06 '13 at 01:02
  • You mean in a list view – Hoan Nguyen May 06 '13 at 01:09
  • It's just as an ArrayList not in a list view yet, I saw no point in putting it into it because ultimately I will not have any button or anything on the interface. – Nitan Shalom May 06 '13 at 01:11
  • You just have to compare the result with all the words (commands) you expected and when one of them match then you do whatever you want – Hoan Nguyen May 06 '13 at 01:14
  • I know that, I was wondering how to do that though.. an if statement? Can you give me a code example? – Nitan Shalom May 06 '13 at 01:26
  • for (String match : matches) { if (match.equal("your command") // do something else if (match.equal("your next command") and so on – Hoan Nguyen May 06 '13 at 01:32
  • Ok, I'm having some problems but I think I can figure out how to do it. Just one unrelated question. I want to be able to call something, and when I call it it will do a few actions... how do I do that? – Nitan Shalom May 06 '13 at 03:07
  • What do you mean by "do a few action"? – Hoan Nguyen May 06 '13 at 03:21
  • As in when you call the "thing", the "thing" is defined by doing some other actions like calling the startListen and the muter... it's substituting for the onClick – Nitan Shalom May 06 '13 at 03:24
  • Just create a method that do whatever action you want and then after the results match your command just call that method – Hoan Nguyen May 06 '13 at 03:41
  • Just a noob question... how do I call this type of method and how do I name it? public void starter (?) Thanks. – Nitan Shalom May 06 '13 at 03:54
  • Any name you you want better yet public void handleCommandA, handleCommandB etc... – Hoan Nguyen May 06 '13 at 03:56
  • ya, but what do I put in the parentesis and do I need to have it in a class? Also, how do I call it? just say "handleComandA;"? – Nitan Shalom May 06 '13 at 03:58
  • What do you put in the parenthesis is depend on what that method need. If none the just handleCommandA(). Yes to call just put handleCommandA. You really need to learn some Java it make your life easier. – Hoan Nguyen May 06 '13 at 04:02
  • I've got everything working very well and everything is on loop technically, the first time around the mute works. After that, I still here the beep. – Nitan Shalom May 06 '13 at 04:24
  • Did you set audio to mute when you call startListening again? – Hoan Nguyen May 06 '13 at 04:29
  • I edited my code, I believe I did, check it out. – Nitan Shalom May 06 '13 at 04:32
  • I have no clue why. How your code even make the speech recognizer to start listen again is beyond me – Hoan Nguyen May 06 '13 at 04:41
  • Well, the loop is that when onResults is called, it calls commandA which sets startListen and setStreamMute, but StreamMute isn't turning to true again so it is not muting... I have no clue what so ever, maybe I need to put an argument in commandA? – Nitan Shalom May 06 '13 at 04:46
  • I understand, so is commandA being called and is it setup correctly? Do you mind checking? – Nitan Shalom May 06 '13 at 04:47
  • I do not understand why commandA is even being called. you call it on the catch block and there is no exception I can see so how commandA can even be called is beyond me – Hoan Nguyen May 06 '13 at 04:49
  • I'm calling commandA in the on create, and in the catch block, is it being called correctly? Should I use a different exception? – Nitan Shalom May 06 '13 at 14:39
  • your grasp of the Java language is not very good. The code you add will not do what you want. You have to learn more Java, I just cannot keep answering question due to insufficient knowledge of basic computer language. – Hoan Nguyen May 06 '13 at 23:24

3 Answers3

4
public class MainActivity extends Activity implements OnClickListener {

ListView lv;
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent; 
boolean reseter = false;
private AudioManager mAudioManager;

Override
protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView)findViewById(R.id.lvVoiceReturn);
Button b= (Button)findViewById(R.id.bVoice);
b.setOnClickListener(this);
boolean available = SpeechRecognizer.isRecognitionAvailable(this);
Log.d("Speech", "available = " + available);
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(new SpeechListener());
mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
        RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
        this.getPackageName());
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);


}

private CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{   
    @Override
    public void onTick(long millisUntilFinished)
    {

    }

    @SuppressWarnings("synthetic-access")
    @Override
    public void onFinish()
    {
        mNoSpeechCountDownOn = false;
        mSpeechRecognizer.cancel();
        mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
    }
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}


@Override
public void onClick(View v) {
 // TODO Auto-generated method stub`
Log.d("speech", "button active");
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);

}
private class SpeechListener implements RecognitionListener {


@Override
public void onBeginningOfSpeech() {
    if (mNoSpeechCountDownOn)
    {
                mNoSpeechCountDownOn = false;
                mNoSpeechCountDown.cancel();
    }
    Log.d("Speech", "onBeginningOfSpeech");

}

@Override
public void onBufferReceived(byte[] buffer) {
    Log.d("Speech", "onBufferReceived");
}

@Override
public void onEndOfSpeech() {
    Log.d("Speech", "onEndOfSpeech");


}

@Override
public void onError(int error) {
    if (mNoSpeechCountDownOn)
    {
                mNoSpeechCountDownOn = false;
                mNoSpeechCountDown.cancel();
    }
    Log.d("Speech", "onError");
}

@Override
public void onEvent(int eventType, Bundle params) {
    Log.d("Speech", "onEvent");
}

@Override
public void onPartialResults(Bundle partialResults) {
    Log.d("Speech", "onPartialResults");
}

@Override
public void onReadyForSpeech(Bundle params) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
    {
                mNoSpeechCountDownOn = true;
                mNoSpeechCountDown.start();
          mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
    }
    Log.d("Speech", "onReadyForSpeech");

}


@Override
public void onResults(Bundle results) {
    Log.d("Speech", "results");
    ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

  // Do whatever you want here

}

@Override
public void onRmsChanged(float rmsdB) {
    //Log.d("Speech", "onRmsChanged");
}



}
}
Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
0

@Hoan Nguyen : The only way I found to mute the "beep" when SpeechRecognizer starts listening was to use the following :

mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);

It is a nasty hack, as I simply want to mute the kind of 'system sound' played by the SpeechRecognizer, but the other solution, using mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true) was not effective.

-1

Try to use this code:

mAudioManager.setStreamMute(AudioManager.VIBRATE_TYPE_NOTIFICATION, true);
tomrozb
  • 25,773
  • 31
  • 101
  • 122
  • setStreamMute requires a stream to mute ... that's not what you are passing in to the method... Additionally, you are muting the system volume stream since the vibrate_type_notification constant happens to be the same as the STREAM_SYSTEM constant. – ekawas May 19 '14 at 01:07
  • Changing the constant to AudioManager.STREAM_SYSTEM would resolve the issue, but SO members have rejected attempts to edit the answer (according to SO policy) and instead force it to be posted as a comment. – Abandoned Cart May 08 '17 at 19:58