20

I'm currently looking into getting a career with JAVA and have decided to start by building an app. I have this code right here that I am using to trigger Speech Recognition.

public class MainActivity extends Activity implements OnClickListener{

private static final int VR_REQUEST = 999;
private ListView wordList;
private final String LOG_TAG = "SpeechRepeatActivity";  
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button speechBtn = (Button) findViewById(R.id.speech_btn);
    wordList = (ListView) findViewById (R.id.word_list);
    PackageManager packManager= getPackageManager();
    List<ResolveInfo> intActivities = packManager.queryIntentActivities
                    (new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
    if (intActivities.size() !=0){
        speechBtn.setOnClickListener(this);
    } else {
        speechBtn.setEnabled(false);
        Toast.makeText(this,"Oops - Speech Recognition Not Supported!", 
                                             Toast.LENGTH_LONG).show();
        }       
}
@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;
}
public void onClick(View v){
   if (v.getId() == R.id.speech_btn) {
    listenToSpeech();
   }
}
    private void listenToSpeech() {
    //start the speech recognition intent passing required data
    Intent listenIntent = 
                     new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    //indicate package
    listenIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                                        getClass().getPackage().getName());
    //message to display while listening
    listenIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say a word!");
    //set speech model
    listenIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 
                                 RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    //specify number of results to retrieve
    listenIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);
    //start listening
    startActivityForResult(listenIntent, VR_REQUEST);
}
    @Override
    protected void onActivityResult(int requestCode, 
                                             int resultCode, Intent data) {
        //check speech recognition result 
        if (requestCode == VR_REQUEST && resultCode == RESULT_OK) {
    //store the returned word list as an ArrayList
    ArrayList<String> suggestedWords = data.
                     getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
    //set the retrieved list to display in the ListView 
            //using an ArrayAdapter
    wordList.setAdapter(new ArrayAdapter<String> 
                                       (this, R.layout.word, suggestedWords));
}
    //this detects which one the user clicks 
    wordList.setOnItemClickListener(new OnItemClickListener(){
        //click listener for items within list
        public void onItemClick(AdapterView<?> parent, 
                                           View view, int position, long id){
        //cast the 
        TextView wordView = (TextView)
        //retrive the chosen word
        String wordChosen= (String) wordView.
        //output for debugging
        Log.v(LOG_TAG, "chosen:" +wordChosen);
     }});
        super.onActivityResult(requestCode, resultCode, data);
  }
}

In this app the user presses a button and gets displayed with the Google Voice Input screen where you can click a button (it actually goes automatically) and you can speak, it will stop and it will display it. I don't want that window to pop up at all though. Instead just let the user click the button and be able to speak and let the app stop and display the text automatically (it already does that).

PLEASE! I understand that there are already answers on the form showing how to do this, in fact a user name JEEZ posted some code right here.

I don't know if I understood where to put this in my project file. I AM A NOOB! If anyone could help clarify this I would GREATLY appreciate your help.

Here is my code:

package com.example.speechrecognizertest;

import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.TextView;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

private static final int VR_REQUEST = 999;
public static final String TAG = null;
private ListView wordList;
private final String LOG_TAG = "SpeechRepeatActivity";
private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent; 
private boolean mIslistening; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button speechBtn = (Button) findViewById(R.id.speech_btn);
    wordList = (ListView) findViewById(R.id.word_list);
    PackageManager packManager = getPackageManager();
    List<ResolveInfo> intActivities = packManager.queryIntentActivities(
            new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    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());
    if (!mIslistening)
    {
        mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
    } else {
        speechBtn.setEnabled(false);
        Toast.makeText(this, "Oops - Speech Recognition Not Supported!",
                Toast.LENGTH_LONG).show();
    }
}


@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
}


@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;
}



protected class SpeechRecognitionListener implements RecognitionListener
{

    @Override
    public void onBeginningOfSpeech()
    {               
        //Log.d(TAG, "onBeginingOfSpeech"); 
    }

    @Override
    public void onBufferReceived(byte[] buffer)
    {

    }

    @Override
    public void onEndOfSpeech()
    {
        //Log.d(TAG, "onEndOfSpeech");
     }

    @Override
    public void onError(int error)
    {
         mSpeechRecognizer.startListening(mSpeechRecognizerIntent);

        //Log.d(TAG, "error = " + error);
    }

    @Override
    public void onEvent(int eventType, Bundle params)
    {

    }

    @Override
    public void onPartialResults(Bundle partialResults)
    {

    }

    @Override
    public void onReadyForSpeech(Bundle params)
    {
        Log.d(TAG, "OnReadyForSpeech"); //$NON-NLS-1$
    }

    @Override
    public void onResults(Bundle results)
    {
        //Log.d(TAG, "onResults"); //$NON-NLS-1$
        ArrayList<String> suggestedWords =      results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        // matches are the return values of speech recognition engine
        // Use these values for whatever you wish to do

        wordList.setAdapter(new ArrayAdapter<String>(this, R.layout.word, suggestedWords));



    }

    @Override
    public void onRmsChanged(float rmsdB)
    {

    }

}
BJ Myers
  • 6,617
  • 6
  • 34
  • 50
Liam Shalon
  • 422
  • 2
  • 5
  • 19
  • Take a look at http://stackoverflow.com/questions/16219601/how-to-make-google-voice-run-continually-in-the-background-on-android/16220820#16220820 – Hoan Nguyen Apr 26 '13 at 04:52
  • Thanks Hoan, just one problem. I saw the code that you referenced from that tutorial but I don't know how to incorporate that into my project. Can you help? – Liam Shalon Apr 26 '13 at 04:59
  • You use activity right? – Hoan Nguyen Apr 26 '13 at 05:01
  • I'm not sure what you mean by that. I have posted all my code in the main document. The activity (I think that means the layout) has a button and a list view. Other than that everything is displayed on the question. (I really wish I could answer your question). Just an edit here- I do not use the activity I do not believe because it is never called. All of this belongs in the code main activity. How would I use the activity? Why would I want to use it and what will it do for me? Thanks so much for your quick responses! – Liam Shalon Apr 26 '13 at 05:13
  • Hi Hoan! I want to comment in your post but for some reason I don't think that I am allowed too... :(. What you gave to me is extremely helpful. I think that the main problem that I encountered was that I didn't know what to replace with what. I understood the first three steps but didn't understand what the onDestroy was and if or if not I should replace the class with something. Very full answer and thanks so much! Also, I know that you are clearly a pro and I would love to try to catch up to your level. If you could suggest anything to help me learn that would help so much! – Liam Shalon Apr 26 '13 at 05:31
  • Every activity has a method call onDestroy which the system called when the activity is destroyed. In Eclipse menu you can select Source --> Override/Implement Methods... and choose onDestroy. If you have an app idea just start writing it, and that is the best way to learn. – Hoan Nguyen Apr 26 '13 at 05:43
  • Ok and just real quick... Nothing has to be replaced in my app with what you wrote correct? – Liam Shalon Apr 26 '13 at 05:52
  • Remove your listenToSpeech and onActivityResult methods. Move your wordList.setAdapter to the onResult of the SpeechRecognitionListener class. – Hoan Nguyen Apr 26 '13 at 05:57
  • Did you not copy my code below to your MainActivity? – Hoan Nguyen Apr 26 '13 at 23:32
  • Hi there, I ran into some errors The method onRmsChanged(float) of type MainActivity must override or implement a supertype method The type MainActivity must implement the inherited abstract method View.OnClickListener.onClick(View) The method onActivityResult(int, int, Intent) is undefined for the type Object The constructor ArrayAdapter(MainActivity.SpeechRecognitionListener, int, ArrayList) is undefined – Liam Shalon Apr 26 '13 at 23:57
  • void is an invalid type for the variable onActivityResult The type MainActivity.SpeechRecognitionListener must implement the inherited abstract method RecognitionListener.onRmsChanged(float) – Liam Shalon Apr 26 '13 at 23:58
  • why don't you post your code. – Hoan Nguyen Apr 27 '13 at 00:04
  • Post Code Where? How? I don't have enough characters to put it into the comments – Liam Shalon Apr 27 '13 at 00:33
  • Edit your post and put in the new code. – Hoan Nguyen Apr 27 '13 at 00:34
  • Feel free to just edit my code that I have posted to the correct code that I should have, briefly explain what you have done and I think that would be perfect! Or you can add on to your answer post. – Liam Shalon Apr 27 '13 at 00:44
  • I edited your second MainActivity class. – Hoan Nguyen Apr 27 '13 at 01:46
  • Everything seems good but using the code that you provided I got some errors that I wasn't sure what to do with. The first error told me that suggestWords cannot be resolved to a variable... wait what? The other error tells me to change the type MainAcitivity to implement the inherited abstract methode View.OnLickListener.onClick(view) I don't really understand these, maybe you can shoot me a tip. – Liam Shalon Apr 27 '13 at 03:53
  • I edited your MainActivity. You need to learn Java a little bit more. – Hoan Nguyen Apr 27 '13 at 04:03
  • Hi Hoan, everything seems to kinda be working I understand everything now but do you think that I may need to have set a certain permission for the app in the manifest? The button is being called but the actual speech recognition isn't being started ( do not have a way to test if the actual class is being called) but I do not think that it is. – Liam Shalon May 03 '13 at 01:22
  • Do you run on a phone or emulator? Emulator may not have Speech Recognition but I am not sure. – Hoan Nguyen May 03 '13 at 01:38
  • Emulator does not have it I know, but I'm running on a galaxy s3. I know that the button is clickable and sending out logs but I don't know if mSpeechRecognizer is being called. What are you thoughts? Also how do I put a log.d inside of the class mSpeechRecognizerIntent to see if it is being called? I'm also recieving errors like (error opening trace file: No such file or directory?) and (s3dReadConfigFile:75) but the app runs on my android phone and sends back logs so maybe or maybe or not that has something to do with it. – Liam Shalon May 03 '13 at 02:14
  • Post a new question with complete code. I will take a look – Hoan Nguyen May 03 '13 at 02:27
  • I posted the question! – Liam Shalon May 03 '13 at 02:40

4 Answers4

39

AndroidManifest.xml

Add the following permission:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

class members

private SpeechRecognizer mSpeechRecognizer;
private Intent mSpeechRecognizerIntent; 
private boolean mIslistening; 

In onCreate

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    .........
    .........
    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    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());


    SpeechRecognitionListener listener = new SpeechRecognitionListener();
    mSpeechRecognizer.setRecognitionListener(listener);

}   

in your button listener just use this code

if (!mIsListening)
{
    mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}

In onDestroy

if (mSpeechRecognizer != null)
{
        mSpeechRecognizer.destroy();
}

Inside your activity create the inner class

protected class SpeechRecognitionListener implements RecognitionListener
{

    @Override
    public void onBeginningOfSpeech()
    {               
        //Log.d(TAG, "onBeginingOfSpeech"); 
    }

    @Override
    public void onBufferReceived(byte[] buffer)
    {

    }

    @Override
    public void onEndOfSpeech()
    {
        //Log.d(TAG, "onEndOfSpeech");
     }

    @Override
    public void onError(int error)
    {
         mSpeechRecognizer.startListening(mSpeechRecognizerIntent);

        //Log.d(TAG, "error = " + error);
    }

    @Override
    public void onEvent(int eventType, Bundle params)
    {

    }

    @Override
    public void onPartialResults(Bundle partialResults)
    {

    }

    @Override
    public void onReadyForSpeech(Bundle params)
    {
        Log.d(TAG, "onReadyForSpeech"); //$NON-NLS-1$
    }

    @Override
    public void onResults(Bundle results)
    {
        //Log.d(TAG, "onResults"); //$NON-NLS-1$
        ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        // matches are the return values of speech recognition engine
        // Use these values for whatever you wish to do
    }

    @Override
    public void onRmsChanged(float rmsdB)
    {
    }
}

EDIT 2015-02-07: Incorporated code from the answers to this question by ZakiMak and Born To Win into the code in this answer to make this one more complete.

Community
  • 1
  • 1
Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
  • The above goes to your MainActivity – Hoan Nguyen Apr 26 '13 at 05:21
  • 2
    When I call mSpeechRecognizer.startListening(mSpeechRecognizerIntent); nothing happens, it never says that it is ready for speech... – Jister13 Jul 19 '14 at 00:47
  • I am having an issue here. At the end I convert the array list into a string and set that String to a TextView... the issue is that no text is actually displayed. Any ideas as to how this can happen? – Ethan Feb 08 '15 at 05:17
  • Does the logcat show the string that you set to a TextView? – Hoan Nguyen Feb 08 '15 at 22:06
  • 1
    On Android 6+ the permission RECORD_AUDIO is one of dangerous ones which means you need to ask user to confirm it to actually acquire it. When you're developing your app and using ADB to debug, you might not be prompted to approve the "dangerous" Record Audio (Microphone) permission, so on the device you need to manually open up the app in Settings and grant the permission. –  Aug 01 '17 at 23:26
7

It's been a long time since the post. Still for those who are looking, the above code provided by Hoan is almost complete, but there is an important line missing. Both in question and answer and I am not sure how it could work without that.

You need to create the SpeechRecognitionListener and set it as a listener for the SpeechRecognizer. Also it has to be done before we make a call to startListening() method of the SpeechRecognizer.

SpeechRecognitionListener listener = new SpeechRecognitionListener(); mSpeechRecognizer.setRecognitionListener(listener);

Then you also need to remove the listener from the onError event.

Paul
  • 7,157
  • 6
  • 32
  • 37
ZakiMak
  • 2,072
  • 2
  • 17
  • 26
7

Don't Forget to add permission of following:-

<uses-permission android:name="android.permission.RECORD_AUDIO" />
Born To Win
  • 3,319
  • 3
  • 19
  • 27
0

I ran into that issue as well. It seems like having startActivityForResult(...) will enable the pop-up mic, then you can handle the response in onActivityResult(). However, simply adding that startActivityForResult messed up my startListening(mSpeechRecognizerIntent), so you may need to do more adjustment.

mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                                     RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                                     this.getPackageName());
startActivityForResult(recognizerIntent, 100);

// call back
onActivityResult(int requestCode, int resultCode, Intent data){...}
6HKyle9
  • 11
  • 3