Search code examples
javaandroidtext-to-speechvoice

Android Studio - Voice search - Crashing on saying number 2 and 4


I have an activity that has voice function. which lets you say 4 words and these words are added into an array. I am want only the second and the last word.

I am converting the second word into a string and the last word into an int (last word is always a number from 1-5).

The code is working fine as long as I don't say 2 or 4. as soon I say those two numbers the app crashes.

how can I fix this?

I tried of thinking of inserting an if statement. for example - if string contains word for, four then it = 4. (rough code).

I have posted the code and stack trace below.

public class Report extends AppCompatActivity {

private static final int REQ_CODE_SPEECH_INPUT = 100;
private TextView mVoiceInputTv;
private ImageButton mSpeakBtn;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.report);


    mVoiceInputTv = (TextView) findViewById(R.id.voiceInput);
    mSpeakBtn = (ImageButton) findViewById(R.id.btnSpeak);
    mSpeakBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            startVoiceInput();
        }
    });

    final String carreg = mVoiceInputTv.getText().toString();


}

private void startVoiceInput() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "e.g- Report fpg563 rating 3");
    try {
        startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
    } catch (ActivityNotFoundException a) {

    }
}

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

    switch (requestCode) {
        case REQ_CODE_SPEECH_INPUT: {
            if (resultCode == RESULT_OK && null != data) {
                ArrayList<String> result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                mVoiceInputTv.setText(result.get(0));

            }
            break;
        }

    }
    if(mVoiceInputTv.getText().toString().contains("report")) {
        input();

    }
}


public void input() {

    String test = mVoiceInputTv.getText().toString();
    String[] ms = test.split(" ");
    List<String> selectedWords = new ArrayList<>();

    for (int i = 0; i < ms.length; i++) {
        selectedWords.add(ms[i]);


        final String carreg = ms[1];
        final String newrating = ms[3];
        final int rating = Integer.parseInt(newrating);





        Response.Listener<String> responseListener = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonResponse = new JSONObject(response);
                    boolean success = jsonResponse.getBoolean("success");
                    if (success) {
                        Intent intent = new Intent(Report.this, Report.class);
                        Report.this.startActivity(intent);
                    } else {
                        AlertDialog.Builder builder = new AlertDialog.Builder(Report.this);
                        builder.setMessage("Reporting Failed")
                                .setNegativeButton("Retry", null)
                                .create()
                                .show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }


        };
        Report_request registerRequest = new Report_request(carreg, rating, responseListener);
        RequestQueue queue = Volley.newRequestQueue(Report.this);
        queue.add(registerRequest);
    }
}

}

Stack Trace:

10-25 17:45:41.449 32501-32501/com.example.naveen.loginregister E/AndroidRuntime: FATAL EXCEPTION: main
  Process: com.example.naveen.loginregister, PID: 32501
  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent {  launchParam=MultiScreenLaunchParams { mDisplayId=0 mFlags=0 }(has extras) }} to activity {com.example.naveen.loginregister/com.example.naveen.loginregister.Report}: java.lang.NumberFormatException: For input string: "for"
      at android.app.ActivityThread.deliverResults(ActivityThread.java:4472)
      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4515)
      at android.app.ActivityThread.-wrap22(ActivityThread.java)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:154)
      at android.app.ActivityThread.main(ActivityThread.java:6682)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
   Caused by: java.lang.NumberFormatException: For input string: "for"
      at java.lang.Integer.parseInt(Integer.java:521)
      at java.lang.Integer.parseInt(Integer.java:556)
      at com.example.naveen.loginregister.Report.input(Report.java:103)
      at com.example.naveen.loginregister.Report.onActivityResult(Report.java:85)
      at android.app.Activity.dispatchActivityResult(Activity.java:7256)
      at android.app.ActivityThread.deliverResults(ActivityThread.java:4468)
      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4515) 
      at android.app.ActivityThread.-wrap22(ActivityThread.java) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:154) 
      at android.app.ActivityThread.main(ActivityThread.java:6682) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410) 

whats up with this downvotes? im asking an honest question. ofcourse the grammer might be bad. but im still learning english. u want me to go to a english classs before i post a question?


Solution

  • This is must be happening because 2 is also the word "to" or "too" which is not going to be convertable into an int unless you are catching those cases. Similarly, as you pointed out 4 is probably being converted to the word "for" which again won't convert to an int unless you specifically catch that case.

    I think you're on the right track, catching those cases where the voice to text is going to hand you a word that sounds like a number but isn't one.

    BUT if you want your code to not crash you need to prepare for any possible input. So you should be catching the exception if it is thrown and then doing the right thing.

    try {
        final int rating = Integer.parseInt(newrating);
    } catch ( NumberFormatException e ) {
        //uhoh couldn't get the number 
        //prompt the user to try again or 
        //do something else that makes sense
    }