Question

I hope I'll be clear enough.

In my app, I have set it so that pressing the back button activates google's voice recognition service. In the onActivityResult, it checks whether the first word is "call" or "text" and proceed accordingly with the rest of the spoken sentence. For text specifically, it goes like "text [contact name] message [message content]" and then sends it using an smsManager. But since it might get the name or the message wrong, I want it to read out the message and the person's name first for confirmation which I did just fine.

The problem is, to confirm or cancel, I want to also use voice recognition. If after the message is read out, the user says something like send and only then it should proceed to send the message. So, what I need to know is how/if can I implement this (newVoiceCommand) in the code below:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
    case RESULT_SPEECH: {
        if (resultCode == RESULT_OK && null != data) {
            s="";
            text = data
                    .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            decide = text.get(0).split("\\s");
            for (int i=1; i<decide.length;i++) s= s+decide[i] + " ";
            if (decide [0].equals("text")){
                if (!s.equals("")){
                    msg = s.split(" message");
                    char[] stringArray = msg[0].toCharArray();
                    stringArray[0] = Character.toUpperCase(stringArray[0]);
                    msg[0] = new String(stringArray);
                    contact = get_Number (test(msg[0]));
                    Intent intent = getIntent();
                    finish();
                    startActivity(intent);
                    String temp = "Are you sure you want to send " + msg[1] + " to " + test(msg[0]);
                    speakOut (temp);

                    if (newVoiceCommand.equals("send")){
                        try {
                            SmsManager smsManager = SmsManager.getDefault();
                            out.append(contact);
                            smsManager.sendTextMessage(contact, null, msg[1], null, null);
                            Toast.makeText(getApplicationContext(), "SMS Sent! to "+msg[0] + " at " +contact,
                                        Toast.LENGTH_LONG).show();
                          } catch (Exception e) {
                            Toast.makeText(getApplicationContext(),
                                "SMS faild, please try again later!",
                                Toast.LENGTH_LONG).show();
                            e.printStackTrace();
                          }
                    }
                    else if (newVoiceCommand.equals("no")) out.append("Not sending");
                }
            }
            else if (decide[0].equals("call")){
                out.append (s);
                if (!s.equals(""))  {
                    call (s);
                }
            }
        }
        break;
    }
    }
}

My current attempt:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
    case RESULT_SPEECH: {
        if (resultCode == RESULT_OK && null != data) {
            s="";
            //Grab the speech results and save them in an arraylist
            text = data
                    .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            //Split each word into an array item
            decide = text.get(0).split("\\s");
            //Re-concatenate the words starting with the second word together
            for (int i=1; i<decide.length;i++) s= s+decide[i] + " ";
            //If the first word is "text", then send an SMS using the rest of the information spoken
            if (decide [0].equals("text")){
                if (!s.equals("")){
                    check (s);
                    Intent spIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                    spIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en_US");

                    try {
                        startActivityForResult(spIntent, RESULT_SPEECH2);
                    } catch (ActivityNotFoundException a) {
                        Toast t = Toast.makeText(getApplicationContext(),
                                "Opps! Your device doesn't support Speech to Text",
                                Toast.LENGTH_SHORT);
                        t.show();
                    }
                    switch (requestCode) {
                    case RESULT_SPEECH2: {
                        if (resultCode == RESULT_OK && null != data) {
                            text2 = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                            s2 = "";
                            if (text2.get(0).equals("send")){
                                smsText (s);
                            }
                            else if (text2.get(0).equals("cancel")) return;
                        }
                    }
Was it helpful?

Solution

In short, all of the voice recognition results are going to come to you through an asynchronous call to onActivityResult. You don't block and wait for the result, so you need a way to determine whether the recognition is in response to a command or a confirmation at the time you receive the result.

This is what the requestCode parameter of Activity.startActivityForResult() is for:

Sometimes you want to get a result back from an activity when it ends. For example, you may start an activity that lets the user pick a person in a list of contacts; when it ends, it returns the person that was selected. To do this, you call the startActivityForResult(Intent, int) version with a second integer parameter identifying the call. The result will come back through your onActivityResult(int, int, Intent) method.

If you use two different values for requestCode (e.g., define private final static int REQUEST_SPEECH_COMMAND = 1, REQUEST_SPEECH_CONFIRMATION = 2) when you start the voice recognition activity, you can respond differently in onActivityResult. Note that you'll need to store the results of the first voice recognition (the action, message, and recipient) so this information will be available the second time around.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top