App crashes if no answer is given - android

My app is a timed math game. Answer as many questions as you can before the timer runs out. When the time runs out, The GameOverActivity is now the current activity. I've realized that if I give no answer, the app will crash. If I give at least 1 answer, the app doesn't crash and everything is normal. I'm not sure where the flaw in my code exista.
This is the Main Activity
package stormy.incremental.randomtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class FastMathActivity extends AppCompatActivity {
int rand1, rand2, randDecider, correctAnswer, falseAnswer, problemsSolved;
String response,sumStr;
MyCountDownTimer myCountDownTimer;
int score;
Random r;
TextView randTV1, randTV2, scoreTV, sumTV, problemsSolvedTV, timerTV;
Button choice1, choice2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_test);
problemsSolved =0;
falseAnswer = 1;
//Initializing TextViews
timerTV = ((TextView) findViewById(R.id.timer));
randTV1 = ((TextView) findViewById(R.id.rand1));
randTV2 = ((TextView) findViewById(R.id.rand2));
sumTV = ((TextView) findViewById(R.id.sum));
scoreTV = ((TextView) findViewById(R.id.score));
problemsSolvedTV = ((TextView) findViewById(R.id.problemsSolved));
choice1 = ((Button) findViewById(R.id.choice1));
choice2 = ((Button) findViewById(R.id.choice2));
//Initializing a Random
r = new Random();
//Set the first question
setRandomProblem();
//Starting the timer
myCountDownTimer = new MyCountDownTimer(timerTV, 5000, 1000);
myCountDownTimer.start();
// Button Listeners
choice1.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
checkResponse((Button)v);
setRandomProblem();
}
});
choice2.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
checkResponse((Button)v);
setRandomProblem();
}
});
}
public void checkResponse(Button v) {
//Convert the response and correctAnswer to String in order to compare values
response = v.getText().toString();
sumStr = Integer.toString(correctAnswer);
//If the user clicks the correct answer, increment score
if ((response.equals(sumStr))) {
score++;
scoreTV.setText(score+"");
}
//Increment the total amount of problems solved
problemsSolved++;
problemsSolvedTV.setText(problemsSolved+"");
//Keep track of the score within the timer
myCountDownTimer.recordScore(score,problemsSolved);
}
private void setRandomProblem() {
//Assigning random values to ints
rand1 = r.nextInt(5 - 1) + 1;
rand2 = r.nextInt(5 - 1) + 1;
randDecider = r.nextInt(2) + 1;
//The correctAnswer of the randoms
correctAnswer = rand1 + rand2;
//Setting the texts of the random values
randTV1.setText(rand1 + "");
randTV2.setText(rand2 + "");
//If the random deciding number is 1, set answer on choice1
if (randDecider == 1) {
choice1.setText(correctAnswer + "");
choice2.setText(correctAnswer + falseAnswer + "");
}
//If the random deciding number is 2, set answer on choice2
else {
choice1.setText(correctAnswer + falseAnswer + "");
choice2.setText(correctAnswer + "");
}
}
#Override
public void onStop(){
super.onStop();
//Stop the timer
myCountDownTimer.cancel();
}
}
This is the GameOverActivity
package stormy.incremental.randomtest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
/**
* Created by kamalu on 12/25/2017.
*/
public class GameOverActivity extends AppCompatActivity {
TextView scoreTV, problemsSolvedTV, percentageTV;
int score, problemsSolved, percentage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameover);
//Initializing TextViews
scoreTV = ((TextView)findViewById(R.id.score));
problemsSolvedTV = ((TextView)findViewById(R.id.problemsSolved));
percentageTV = ((TextView)findViewById(R.id.percentage));
//Opening Bundle and assigning values
Bundle extras = getIntent().getExtras();
score = extras.getInt("score");
problemsSolved = extras.getInt("problemsSolved");
//calculating the accuracy
percentage = (score/problemsSolved)*100;
//Displaying the score
percentageTV.setText(percentage+"");
scoreTV.setText(score+"");
problemsSolvedTV.setText(problemsSolved+"");
}
//Start the game over
public void retry(View v){
Intent retryIntent = new Intent(GameOverActivity.this, FastMathActivity.class);
startActivity(retryIntent);
}
public void onBackPressed()
{
}
}
This is the Timer. I believe it to be important to note that the onFinish() method in this class starts the GameOverActivity.
package stormy.incremental.randomtest;
import android.content.Intent;
import android.os.CountDownTimer;
import android.widget.TextView;
public class MyCountDownTimer extends CountDownTimer {
TextView textCounter;
int score,problemsSolved;
public MyCountDownTimer(TextView textCounter, long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
this.textCounter = textCounter;
}
#Override
public void onTick (long millisUntilFinished){
textCounter.setText(String.valueOf(millisUntilFinished / 1000));
}
#Override
public void onFinish () {
Intent gameOverIntent = new Intent(textCounter.getContext(), GameOverActivity.class);
gameOverIntent.putExtra("score", score);
gameOverIntent.putExtra("problemsSolved", problemsSolved);
textCounter.getContext().startActivity(gameOverIntent);
}
//Keep track of the scores
public void recordScore(int score,int problemsSolved){
this.problemsSolved = problemsSolved;
this.score = score;
}
}

You should check:
//calculating the accuracy
percentage = (score/problemsSolved)*100;
if problemsSolved = 0, your app will crash with exeptions: java.lang.ArithmeticException
You can refer:
if (problemSolved != 0){
//calculating the accuracy
percentage = (score/problemsSolved)*100;
} else {
// handle with problemSolved = 0;
}
I hope it can help your problem!

Related

Making a line of code repeat in android every second

This is the line i want to repeat.
handler.postDelayed(runnableCode, 1);
This app is a tycoon app and so the user can buy upgrades and if they tap the button the get $$ and so when they buy upgrades keeping the value up-to-date is required.
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter = 0;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int Test = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.postDelayed(runnableCode, 1);
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
finish();
}
});
}
public int ButtonCounter(int Counter){
Counter+=1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter+=add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
// Do something here on the main thread
Counter = AutoCounter(Counter,Test);
Display(Counter, myTextView);
}
};
}
handler.postDelayed(runnableCode, 1);
call that line inside onResume() method. Make sure your show an AlertDialog to the user whenever he or she hits the button to get $$. Since the AlertDialog pops up everytime the user tries to buy $$. onResume() will be called.
Try this
private void startAnimation() {
countDownTimer = new CountDownTimer(700, 500) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
//your code to repeat
}
start();
}
}.start();
}

Method stops running after switching activities

In this app the users score is supposed to increase every second or so, and they can use that score and buy upgrades from the second Activity. When the user starts the app the program works fine, but when they go from the first activity to the second and back it stops updating the textview with the score that increases every second. Can you guys explain whats going on?
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
if (bundle.containsKey("Count")) {
Counter = bundle.getInt("Count");
}
if (bundle.containsKey("Add")) {
add = bundle.getInt("Add");
}
}
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter= AutoCounter(Counter, add);
Display(Counter);
handler.postDelayed(this, 1000);
}
},100);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}
You start the counting handler only inside onCreate() method.
When you go back from SecondActivity to MainActivity the onResume() method is called, So
You need to start the counting inside onResume() method.
P.S Make sure to check for nulls before updating you UI from postDelay().
Your Activity might be destroyed by the time the code runs, make sure your TextView is not null before updating.

Want button to be visible after being invisible

I have a problem with a button to be invisible when I want. In my if statement I have declared the exerciseButtonDone to first to be invisible but then after the final countdown I want it to become visible.
As my code is right now the button is visible all the time.
package org.example.anders.eazy;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.os.Vibrator;
import java.util.concurrent.TimeUnit;
public class ExerciseActivity extends Activity {
String[] exerciseList;
TextView textTimer,workoutTextview,exerciseTextView;
int setsChosen;
int counter = 0;
int timeChosen;
boolean togglebuttonpress;
Button exerciseButtonDone;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exerciseList = getResources().getStringArray(R.array.heavy_chest_arms);
setContentView(R.layout.activity_exercise);
exerciseButtonDone=(Button)findViewById(R.id.buttonActiveExcercise);
Intent intent = getIntent();
String selectedWorkout = intent.getExtras().getString("workoutName");
togglebuttonpress=intent.getExtras().getBoolean("togglebuttonPress");
textTimer = (TextView) findViewById(R.id.timeUntilFinished);
//workoutTextview = (TextView) findViewById(R.id.workoutChosen);
//workoutTextview.setText(selectedWorkout);
if(togglebuttonpress){
exerciseButtonDone.setVisibility(View.INVISIBLE);
setsChosen =intent.getExtras().getInt("setsChosen");
int timePass = intent.getExtras().getInt("timeChosen");
timeChosen=timePass;
counter = 0;
runCountDownTimer();
exerciseButtonDone.setVisibility(View.VISIBLE);
}
else {
textTimer.setText("");
exerciseButtonDone.setVisibility(View.VISIBLE);
}
//exerciseTextView= (TextView) findViewById(R.id.exerciseNow);
//exerciseTextView.setText(exerciseList[i]);
}
public void runCountDownTimer() {
if (counter < setsChosen) {
new CountDownTimer(timeChosen * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long millis = millisUntilFinished;
String hms = String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
System.out.println(hms);
textTimer.setText(hms);
}
#Override
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
counter++;
v.vibrate(500);
runCountDownTimer();
}
}.start();
}
textTimer.setText("Complete");
}
}
You are setting the button invisible and then immediately visible.
if(togglebuttonpress){
exerciseButtonDone.setVisibility(View.INVISIBLE);
...
exerciseButtonDone.setVisibility(View.VISIBLE);
}
move exerciseButtonDone.setVisibility(View.VISIBLE); from its current location to where the countdown timer actually finishes, which I now see is runCountDownTimer()
if (counter < setsChosen) {
new CountDownTimer(timeChosen * 60000, 1000) {
...
}
} else {
exerciseButtonDone.setVisibility(View.VISIBLE);
}
you'll still need to make execerciseButtonDone final... and move it to the right scope, thank you alex. It needs to be a class variable, over by say boolean togglebuttonpress;
you COULD do findViewById again, but that's redundant and unnecessary.
I added an if statement that checked if loop was done. It worked.
public void onFinish() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
counter++;
v.vibrate(500);
runCountDownTimer();
if (counter == setsChosen)
{
exerciseButtonDone.setVisibility(View.VISIBLE);
}
}

Android CountDown Timer in UI Thread

I try to code a CountDownTimer which can be repeated several times. My code works fine... But just one time. I don't understand why the repeated action is not done :-(
Here is my code :
package com.bigmat.MyTimer;
import android.app.Activity;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.widget.*;
public class MainActivity extends Activity {
private TextView inputDuration;
private TextView tvCdTimer;
private Button start;
CountDownTimer myCdTimer;
NumberPicker npDuration;
CheckBox isRepeat;
TextView tvRepeat;
int nbRepeat;
int count;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
inputDuration = (TextView) findViewById(R.id.tvInputDuration);
tvCdTimer = (TextView) findViewById(R.id.tvCdTimer);
start = (Button) findViewById(R.id.btStart);
npDuration = (NumberPicker) findViewById(R.id.npDuration);
npDuration.setMaxValue(60);
npDuration.setMinValue(0);
isRepeat = (CheckBox) findViewById(R.id.cbRepeat);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
count=0;
tvRepeat = (TextView) findViewById(R.id.nbRepeat);
if (tvRepeat.getText().toString().length() > 0) {
nbRepeat = Integer.parseInt(tvRepeat.getText().toString());
} else {
nbRepeat = 1;
}
runTimer();
}
});
}
public void runTimer(){
Log.i("CDT", "value of npDuration is : "+npDuration.getValue());
if (npDuration.getValue() > 0 && nbRepeat > 0) {
// create a timer
myCdTimer = new CountDownTimer(npDuration.getValue()*1000, 1000) {
public void onTick(long millisUntilFinished) {
tvCdTimer.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
tvCdTimer.setText("Done ! ");
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
count++;
//condition
if (count < nbRepeat) {
Log.i("MyTimer", "value of nbRepeat :" + nbRepeat + " value of count : " + count);
myCdTimer.cancel();
myCdTimer.start();
}
}
}.start();
} else {
Toast.makeText(getApplicationContext(), "Timer is set on 0 seconds !!!", Toast.LENGTH_LONG).show();
}
}
}
Thanks in advance!

Closing Android Game After 5 Seconds

I'm tring to build an simple android game.
Users answer the questions, when the answer is correct, it is continue..
I want to add time control for each answer.
I tried to add handler function, but I didn't.
My Code;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class EasyGameActivity extends Activity {
public int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_easygame);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
finishScreen();
}
}, 5000);
startGame();
}
private void startGame() {
// TODO Auto-generated method stub
Button b1 = (Button)findViewById(R.id.answer_one);
Button b2 = (Button)findViewById(R.id.answer_two);
Button b3 = (Button)findViewById(R.id.answer_three);
Button b4 = (Button)findViewById(R.id.answer_four);
Random number = new Random();
int first = number.nextInt(100)+1;
int second = number.nextInt(100)+1;
int answer = first + second;
int rnd1 = answer + 1;
int rnd2 = answer + 2;
int rnd3 = answer - 1;
final String a = Integer.toString(answer);
String b = Integer.toString(rnd1);
String c = Integer.toString(rnd2);
String d = Integer.toString(rnd3);
((TextView) findViewById(R.id.display)).setText(Integer.toString(first) + '+' + Integer.toString(second));
List<Button> buttons = Arrays.asList(b1, b2, b3, b4);
List<String> texts = Arrays.asList(a, b, c, d);
Collections.shuffle(texts);
int i = 0;
OnClickListener onClick = new OnClickListener() {
public void onClick(View view) {
Button button = (Button) view;
String value = (String) button.getText();
if(value == a) {
checkTrue();
} else {
finishScreen();
}
}
};
for(Button button : buttons) {
button.setText(texts.get(i++));
button.setOnClickListener(onClick);
}
}
private void checkTrue() {
score++;
((TextView) findViewById(R.id.score)).setText(Integer.toString(score));
startGame();
}
private void finishScreen() {
score = 0;
startActivity (new Intent("com.bsinternet.mathfast.RESTARTGAMESCREEN"));
finish();
}
}
How can I add time control. Thanks.
This bit of code doesn't look right
if(value == a) {
checkTrue();
} else {
finishScreen();
}
You should be using equals() to check for String equality. At the moment you are checking only object equality, which will evaluate to False, and the code will never call checkTrue().
Do this instead:
if(value.equals(a) {
checkTrue();
} else {
finishScreen();
}

Categories

Resources