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.
Problem:
The application keep crashing right before the new next button appears with different images when I attempt to press the next button.
I think that it has something to do with the random number generator or an issue with the if statements i placed.
I am getting no error message. I am not sure what is causing the issue. When I do run the apk file, when it crash it says "unfortunately, pic has stopped"
"pic" is the app name.
EDIT:
When i ran the app through the emulator I got an runtime error message, shown below
The next button is clicked and changes to the next image which is randomizes by the code:
randomNum = (random.nextInt(UnSpokenList.size()) + 1);
onActivityResult
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;
TextView speechInput;
TextView matchOrNot;
TextView passTitle;
TextView counterDisplay;
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;
int passCounter;
@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);
passTitle = (TextView) findViewById(R.id.passedTitle);
counterDisplay = (TextView) findViewById(R.id.passCounterText);
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.last2);
pass.setClickable(true);
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);
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);
passCounter = 0;
restart.setVisibility(View.INVISIBLE);
mainMenu.setVisibility(View.INVISIBLE);
passTitle.setVisibility(View.INVISIBLE);
counterDisplay.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) {
}
/**
* When the next button is pressed, this function handles the next random image to be displayed
* @param view
*/
public void onNext(View view){
if(view.getId() == R.id.nextButton){
speechInput.setText("");
matchOrNot.setText("");
randomNum = (random.nextInt(UnSpokenList.size()) + 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.last2){
if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());
image.setImageResource(resID);
speechBtn.setClickable(true);
pass.setClickable(false);
pass.setVisibility(View.INVISIBLE);
}else {
onGameOver();
}
}
}
public void onGameOver(){
}
/**
* when the user clicks the passed button this function is called.
* It takes the previous image and make sure it does not pop-up again for the next image and then reproduce a different image
* @param view
*/
public void onPass(View view){
}
public void onResetPic(View view){
}
public void reset(){
}
public void MainMenu(View view){
}
/**
* shows speech input dialog
*/
public void promptSpeechInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.ACTION_RECOGNIZE_SPEECH, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say a Word from our word bank!");
try {
startActivityForResult(intent, VR_Request);
} catch (ActivityNotFoundException a) {
Toast.makeText(Pictionary.this, "Oops, your device doesn't support speech recognition,", Toast.LENGTH_LONG).show();
}
}
/**
* detects and recieve speech input
* @param requestCode
* @param resultCode
* @param intent
*/
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);
}
}else{
speechInput.setText("");
matchOrNot.setTextColor(Color.RED);
matchOrNot.setText("TRY AGAIN!");
pass.setVisibility(View.VISIBLE);
pass.setClickable(true);
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
}
08-17 15:58:31.083 13036-13036/com.example.speechtotext E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.speechtotext, PID: 13036
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
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.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
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.onlastPair(Main.java:222)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
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 15:58:33.495 13036-13036/com.example.speechtotext I/Process: Sending signal. PID: 13036 SIG: 9
08-17 15:58:33.966 17345-17345/com.example.speechtotext W/System: ClassLoader referenced unknown path: /data/app/com.example.speechtotext-2/lib/x86
08-17 15:58:34.302 17345-17345/com.example.speechtotext W/System: ClassLoader referenced unknown path: /data/app/com.example.speechtotext-2/lib/x86
08-17 15:58:34.673 17345-17345/com.example.speechtotext W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-17 15:58:34.748 17345-17386/com.example.speechtotext D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
[ 08-17 15:58:34.759 17345:17345 D/ ]
HostConnection::get() New Host Connection established 0xaa23f4c0, tid 17345
08-17 15:58:34.828 17345-17386/com.example.speechtotext I/OpenGLRenderer: Initialized EGL, version 1.4
08-17 15:58:34.885 17345-17386/com.example.speechtotext W/EGL_emulation: eglSurfaceAttrib not implemented
08-17 15:58:34.888 17345-17386/com.example.speechtotext W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaa23e540, error=EGL_SUCCESS
public void onlastPair(View view){
if(view.getId() == R.id.last2){
if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());
image.setImageResource(resID);
speechBtn.setClickable(true);
pass.setClickable(false);
pass.setVisibility(View.INVISIBLE);
}else {
onGameOver();
}
}
}
if(!UnSpokenList.get(UnSpokenList.size()).contains("Word Bank:")) {
resID = res.getIdentifier(UnSpokenList.get(UnSpokenList.size()), "drawable", getApplication().getPackageName());
public void onlastPair(View view){
if(view.getId() == R.id.last2){
if(!UnSpokenList.get(1).isEmpty()) {
int max = UnSpokenList.size();
resID = res.getIdentifier(UnSpokenList.get(max), "drawable", getApplication().getPackageName());
image.setImageResource(resID);
speechBtn.setClickable(true);
pass.setClickable(false);
pass.setVisibility(View.INVISIBLE);
}else {
onGameOver();
}
}
}
int max = UnSpokenList.size();
randomNum = (random.nextInt(UnSpokenList.size()) + 1);
is incorrect
nextInt(15)
gives # 0-14
if your UnSpokenList.size()
== 15, that means it has indicies from 0-14
so if you do random.nextInt(UnSpokenList.size()) + 1)
you are actually rng'ing for numbers, 15+1, which will be from 0-15
15 will fall outside your indicies of 0-14
to ignore your UnSpokenList(0)
...
you need to change it to: random.nextInt(UnSpokenList.size() - 1) + 1
a size 15-1 will rng 0-13, then +1, will make it 1-14 which is perfect for UnSpokenList(1)
- UnSpokenList(14)
we can test this for UnSpokenList.size()
= 2
random.nextInt(2 - 1) + 1
= only-0 + 1 = only-1
EDIT
if(!UnSpokenList.get(1).isEmpty())
are you trying to check if your list has more than 1 item? if so, yours can throw index-error, it should be if (UnSpokenList.size() > 1)
then once again, int max = UnSpokenList.size() ... UnSpokenList.get(max)
you're giving it an index out of bounds, 0-14 but you get(15), it's not going to work