Brandon Brandon - 3 months ago 6
Android Question

Speech to text result = null error

Brief Description: The application will display random images to the user based off the words from the word bank file and the user will have to identify the name of the image, (single word). The user can either "pass" by clicking the pass button or identify the image and then the "next" button will pop up directing them to the next image.
At the last image, the next button will be replaced by "Continue" button which will lead the user to the game over screen

Problem:
Every time, i reached the last picture and attempt to answer it or when the "continue" button appears, and I click it also causes the game to crash. "unfortunately, pic has stopped"

The error message is pointing to the line:

if (wordBANK.contains(result.get(0).toLowerCase()) && UnSpokenList.get(randomNum).contains(result.get(0).toLowerCase())) {


I don't see any problem with this line as it been working fine for the previous images until the very last image.

Main.Java

public class Main extends Activity implements AdapterView.OnItemSelectedListener {

private static final int VR_Request = 100;

Button restart;
Button mainMenu;
Button pass;
Button next;
Button last2image;
Button gameOver;

TextView speechInput;
TextView matchOrNot;

String[] wordBank;
ArrayList<String> wordBANK;

Spinner wordList;
Spinner SpokenWords;

ArrayList<String> UnSpokenList;
ArrayList<String> SpokenList;
ArrayAdapter<String> wordList_adapter;
ArrayAdapter<String> SpokenList_adapter;

ImageButton speechBtn;

ImageView image;
Resources res;
int resID;

Random random;
int randomNum;

int previous;

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

speechInput = (TextView) findViewById(R.id.english_word1);
matchOrNot = (TextView) findViewById(R.id.matchOrNot1);


wordBank = getResources().getStringArray(R.array.Words);

speechBtn = (ImageButton) findViewById(R.id.mic_pic_button1);

wordBANK = new ArrayList<String>(Arrays.asList(wordBank));
image = (ImageView) findViewById(R.id.imageView1);
res = getResources();

restart = (Button) findViewById(R.id.restartButton1);
mainMenu = (Button) findViewById(R.id.mainMenubutton1);
pass = (Button) findViewById(R.id.passButton);
next = (Button) findViewById(R.id.nextButton);
last2image = (Button) findViewById(R.id.last2image);
gameOver = (Button) findViewById(R.id.gameOverTime);

wordList = (Spinner) findViewById(R.id.wordsList1);
SpokenWords = (Spinner) findViewById(R.id.spokenWords1);

UnSpokenList = new ArrayList<String>(Arrays.asList(wordBank));
SpokenList = new ArrayList<String>(wordBank.length+1);

UnSpokenList.add(0, "Word Bank:");
SpokenList.add(0,"Spoken Words:");
wordList_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, UnSpokenList);
wordList_adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
wordList.setAdapter(wordList_adapter);
SpokenList_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, SpokenList);
SpokenList_adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
SpokenWords.setAdapter(SpokenList_adapter);

random = new Random();
randomNum = (random.nextInt(UnSpokenList.size()-1)+1);
resID = res.getIdentifier(UnSpokenList.get(randomNum), "drawable", getApplication().getPackageName());
image.setImageResource(resID);

pass.setClickable(true);
pass.setVisibility(View.VISIBLE);
next.setClickable(false);
next.setVisibility(View.INVISIBLE);
speechBtn.setClickable(true);
last2image.setVisibility(View.INVISIBLE);
last2image.setClickable(false);
gameOver.setVisibility(View.INVISIBLE);
gameOver.setClickable(false);

restart.setVisibility(View.INVISIBLE);
mainMenu.setVisibility(View.INVISIBLE);

}

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
parent.getItemAtPosition(position);
}

@Override
public void onNothingSelected(AdapterView<?> parent) {

}

public void onMicButton(View view) {
}

public void onNext(View view){
if(view.getId() == R.id.nextButton){
speechInput.setText("");
matchOrNot.setText("");

randomNum = (random.nextInt(UnSpokenList.size()-1) + 1);

resID = res.getIdentifier(UnSpokenList.get(randomNum), "drawable", getApplication().getPackageName());
image.setImageResource(resID);

next.setClickable(false);
next.setVisibility(View.INVISIBLE);

pass.setClickable(true);
pass.setVisibility(View.VISIBLE);

speechBtn.setClickable(true);
}
}

/**
* This function occurs when the user plays all the way to last 2 image left in game
*/
public void onlastPair(View view){
if(view.getId() == R.id.last2image){

speechInput.setText("");
matchOrNot.setText("");

resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()-1), "drawable", getApplication().getPackageName());
image.setImageResource(resID);

speechBtn.setClickable(true);

next.setClickable(false);
next.setVisibility(View.INVISIBLE);
pass.setClickable(true);
pass.setVisibility(View.VISIBLE);
last2image.setClickable(true);
last2image.setVisibility(View.INVISIBLE);

if(UnSpokenList.size() == 2){
pass.setClickable(false);
}
}
}

public void onGameOver(View view){
if(view.getId() == R.id.gameOverTime) {
speechInput.setTextColor(Color.RED);
speechInput.setText("GAME OVER!");
matchOrNot.setText("");
image.setImageBitmap(null);
restart.setVisibility(View.VISIBLE);
mainMenu.setVisibility(View.VISIBLE);

pass.setVisibility(View.INVISIBLE);
next.setVisibility(View.INVISIBLE);
last2image.setVisibility(View.INVISIBLE);
gameOver.setVisibility(View.INVISIBLE);
}
}

public void onPass(View view){

}


public void onResetPic(View view){

}


public void reset(){
}

public void MainMenu(View view){

}

public void promptSpeechInput() {

}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if(requestCode == VR_Request && resultCode == RESULT_OK) {
ArrayList<String> result = intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

if (wordBANK.contains(result.get(0).toLowerCase()) && UnSpokenList.get(randomNum).contains(result.get(0).toLowerCase())) {
speechInput.setText(result.get(0).toUpperCase());

matchOrNot.setTextColor(Color.GREEN);
matchOrNot.setText("CORRECT!");

UnSpokenList.remove(result.get(0).toLowerCase());
SpokenList.add(result.get(0).toLowerCase());

pass.setClickable(false);
pass.setVisibility(View.INVISIBLE);

speechBtn.setClickable(false);

if (UnSpokenList.size() > 3) {
next.setClickable(true);
next.setVisibility(View.VISIBLE);
} else {
last2image.setVisibility(View.VISIBLE);
last2image.setClickable(true);
}
if (UnSpokenList.size() == 1) {
last2image.setVisibility(View.INVISIBLE);
last2image.setClickable(false);
next.setVisibility(View.INVISIBLE);
next.setClickable(false);
gameOver.setVisibility(View.VISIBLE);
gameOver.setClickable(true);
}
}else{
speechInput.setText(result.get(0).toLowerCase());

matchOrNot.setTextColor(Color.RED);
matchOrNot.setText("TRY AGAIN!");

pass.setVisibility(View.VISIBLE);
pass.setClickable(true);
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
}


Error Message:

08-17 23:46:18.397 27287-27287/com.example.speechtotext D/AndroidRuntime: Shutting down VM
08-17 23:46:18.397 27287-27287/com.example.speechtotext E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.speechtotext, PID: 27287
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { (has extras) }} to activity {com.example.speechtotext.Main}: java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.speechtotext.Main.onActivityResult(Main.java:343)
at android.app.Activity.dispatchActivityResult(Activity.java:6428)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) 
at android.app.ActivityThread.-wrap16(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
08-17 23:46:21.356 27287-27287/com.example.speechtotext I/Process: Sending signal. PID: 27287 SIG: 9


Any ideas? Thank You in advance!

Answer

It looks like you are removing an element from UnSpokenList in onActivityResult but not altering the value of randomNum prior to getting the final image.

Add the following logging above the line where the app crashes and you'll see the error:

            Log.i("TAG", "The array size is : " + UnSpokenList.size());
            Log.i("TAG", "Attempting to get random position: " + randomNum);