Android Stop toast notification programmatically? - java

Is there a way I can stop a toast message programmatically?
Say I have a button which I click to scroll through toast messages, and in the onclick event I wanted to stop all in the queue and just show the new one, how would I do that?
A simplified version of my code is below -
Code:
public class Help extends Activity{
LinearLayout background;
int screenNo = 1;
Toast toast;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.help);
background = (LinearLayout) findViewById(R.id.helpLayout);
ImageButton next = (ImageButton) findViewById(R.id.imageButtonNext);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
toast.cancel();
showNextScreen();
}});
}
private void showMessageBox(String title, String msg) {
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setTitle(title);
b.setMessage(msg);
b.setPositiveButton("Next", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
showNextScreen();
}});
b.setNegativeButton("Quit Help", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
returnHome();
}});
b.show();
}
private void showNextScreen() {
int time = 7000;
String tstMsg = "error";
switch (screenNo) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
toast.cancel();
returnHome();
break;
default:
break;
}
if(screenNo < 5)
{
toast=Toast.makeText(this, tstMsg, time);
toast.setGravity(Gravity.BOTTOM, 0, 0);
toast.show();
screenNo++;
}
}
}

This is how i achieved this one.
public static Toast toastShow;
public void showToast(Activity actRef, String message) {
if (toastShow == null
|| toastShow.getView().getWindowVisibility() != View.VISIBLE) {
toastShow = Toast.makeText(actRef, message, Toast.LENGTH_SHORT);
toastShow.setGravity(Gravity.CENTER, 0, 0);
toastShow.show();
}
}
define above code in separate class and instantiate that class where you want show message,you are done with it.

Create a custom global object
private Toast toast;
Initialize it in onCreate
toast = Toast.makeText(YOUR_CLASS_NAME.this, "", Toast.LENGTH_SHORT);
Whenever you need to show a Toast
toast.setText("Hi....");
toast.show();
To kill all the message based on requirement onPause or onDestroy
toast.cancel();

You're all free to cancel the Toast object.

Related

Android Spinner how to update the selected position (getSelectedItemPosition())?

So I have a Spinner and a EditText to login. The array of the Spinner owns "Anonymous" and " Owner" (means "Anonymous" is 0 and "Owner" is 1 in the array). When you choose "Anonymous" the password is "0000" and when you choose "Owner" the password is "1234".
But when I choose "Owner", the password "1234" is wrong and the Logcat shows "Anonymous". How can I make "Owner" selected? Maybe getSelectedItemPosition() is wrong?
My Code:
public class PinEnterActivity extends AppCompatActivity {
Button nextButton;
EditText pinEditText;
Spinner pinRoleSpinner = null;
private String TAG = "PinEnterActivity";
private Byte selectedUserRole = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pin_enter);
nextButton = findViewById(R.id.nextActivity)
pinEditText = findViewById(R.id.pinET);
pinRoleSpinner = findViewById(R.id.roleSpinner);
selectedUserRole = (byte) pinRoleSpinner.getSelectedItemPosition();
switch (selectedUserRole) {
case 0:
Log.i(TAG, "Anonymous");
SharedPreferences sharedpreferences = getSharedPreferences("My_Prefs", 0);
final String password = sharedpreferences.getString("pass", "");
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (pinEditText.getText().toString().equals("0000")) {
Intent intent = new Intent(PinEnterActivity.this, NextActivity.class);
startActivity(intent);
} else {
pinEditText.setError("Password incorrect");
Animation shake = AnimationUtils.loadAnimation(PinEnterActivity.this, R.anim.shake);
pinEditText.startAnimation(shake);
return;
}
}
});
break;
case 1:
Log.i(TAG, "Owner");
SharedPreferences preferences = getSharedPreferences("My_Prefs", 0);
final String password2 = preferences.getString("pass", "");
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (pinEditText.getText().toString().equals("1234")) {
Intent intent = new Intent(PinEnterActivity.this, NextActivity.class);
startActivity(intent);
}else{
pinEditText.setError("Password incorrect");
Animation shake = AnimationUtils.loadAnimation(PinEnterActivity.this, R.anim.shake);
pinEditText.startAnimation(shake);
return;
}
}
});
}
}
I finally found out the right answer.
pinRoleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch(selectedUserRole) {
case 0:
Log.i(TAG, "Anonymous");
// Code
break;
case 1:
Log.i(TAG, "Owner");
// Code
break;
default;
// Code
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});

System services not available to Activities before onCreate() while opening a Dialog from RecyclerView

I'm having this error out of the blue and have no idea what's causing it or where it has come from.
Basically I've got a RecyclerView that gets populated with products. When a product is selected, I've got a custom Dialog that pops up where the user can increase product quantity or remove the product. This all works, however if I click the same product a second time it crashes the app with the following error:
System services not available to Activities before onCreate()
This is my RecyclerView.Adapter with the onBindViewHolder()
public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.MyViewHolder>{
#Override
public void onBindViewHolder(#NonNull OrderAdapter.MyViewHolder holder, int position) {
final Item Item = ItemList.get(position);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog = new Dialog(context,R.style.Custom_Theme_Dialog);
//Code breaks on this line
dialog.setContentView(R.layout.dialog_cart_edit);
cartProdDesc = dialog.findViewById(R.id.lblcartProdDesc);
cartQuantity = dialog.findViewById(R.id.edit_quantity);
btnDone = dialog.findViewById(R.id.btn_dialog_done);
btnRemove = dialog.findViewById(R.id.btn_dialog_remove);
addQuantity = dialog.findViewById(R.id.addition_action);
minusQuantity = dialog.findViewById(R.id.minus_action);
cartProdDesc.setText(cartItem.getProductDescription());
cartPackSize.setText(cartItem.getPackSize());
addQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
quantity = Integer.parseInt(cartQuantity.getText().toString());
} catch (NumberFormatException nf) {
Log.e("Number Exception","Number Is Blank");
quantity = 0;
} catch (Exception e){
Log.e("ERROR",e.toString());
}
cartQuantity.setText(String.valueOf(++quantity));
}
});
minusQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
quantity = Integer.parseInt(cartQuantity.getText().toString());
} catch (NumberFormatException nf) {
Log.e("Number Exception","Number Is Blank");
quantity = 0;
} catch (Exception e){
Log.e("ERROR",e.toString());
}
cartQuantity.setText(String.valueOf(--quantity));
}
});
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(cartQuantity.getText().toString().isEmpty() || cartQuantity.getText().toString().equals("0") || cartQuantity.getText().toString().contains("-")){
cartQuantity.setError("Enter a valid quantity");
} else {
newQuantity = cartQuantity.getText().toString();
db.updateCartItem(new CartItem(cartItem.getId(),cartItem.getProductCode(),cartItem.getBarcode(),cartItem.getNappiCode(),cartItem.getProductDescription(),cartItem.getPackSize(),newQuantity));
updateDataSet();
notifyDataSetChanged();
dialog.dismiss();
}
}
});
btnRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DialogInterface.OnClickListener dialogClickListner = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
db.deleteCartItem(cartItem.getId());
updateDataSet();
dialog.dismiss();
break;
case DialogInterface.BUTTON_NEGATIVE:
dialog.dismiss();
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Are you sure you want to remove " + cartItem.getProductDescription()).setPositiveButton("Yes",dialogClickListner).setNegativeButton("No",dialogClickListner).show();
}
});
dialog.show();
}
});
}
}
I've got a private Dialog dialog; declaration further up on the Activity in case anyone was wondering.
The code breaks on the dialog = new Dialog(context,R.style.Custom_Theme_Dialog); however if I comment out the dialog.show() at the end I have no issues, apart from the dialog not showing, but that tells me that the problem isn't with the assigning of the dialog, or am I wrong on this train of thought ?
This is a line of code in my OrderActivity where I'm calling the adapter, I'm sending the context from here.
OrderAdapter = new OrderAdapter(this,ItemList);
This is my constructor where I'm assigning Context
public OrderAdapter(Context context, List<CartItem> cartItemList){
this.context = context;
this.cartItemList = cartItemList;
}
Depending on where that Context is coming from exactly, it might have already been "destroyed" by the time onClick() is called (well not really, because the Dialog is holding an implicit reference to it). In this case this is also a memory leak.
I'd suggest you to change the following:
#Override
public void onClick(View view) {
dialog = new Dialog(context, R.style.Custom_Theme_Dialog);
To this:
#Override
public void onClick(View view) {
dialog = new Dialog(view.getContext(), R.style.Custom_Theme_Dialog);
This way you'll always reference the Context the corresponding View is associated with.

Passing data from one activity to another when choosing a menu option from action bar in Android app

I don't know if anyone can offer some guidance on this.
I have a main class where a user will input their name. I then want the user to choose a game from the options available in the action/app bar. When they choose their game, the name they entered in the main class will then be showing on the game class. I hope that makes sense?
I know this involves passing data from one activity to another using intents but every tutorial I see involves setting up a button in the main class (so using something like onclicklistener) but I don't want a button. I want choosing the menu option to do the same job but I can't find anywhere how to do it.
Thanks in advance.
EDIT - ATTEMPTED CODE ADDED
Main class:
public class GameCentral extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_central_layout);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.commonmenus, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.guessingGame) {
startActivity(new Intent(this, Task3Activity.class));
switch (item.getItemId()) {
case R.id.playerNameEntered:
startActivity(this, Task3Activity.class).putExtra(playerNameInput, value);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
else if (id ==R.id.placeOne) {
Toast.makeText(this, "Game Placeholder One option is Clicked", Toast.LENGTH_SHORT).show();
}
else if (id ==R.id.placeTwo) {
Toast.makeText(this, "Game Placeholder Two option is Clicked", Toast.LENGTH_SHORT).show();
}
else if (id ==R.id.placeThree) {
Toast.makeText(this, "Game Placeholder Three option is Clicked", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
Game Class
public class Task3Activity extends GameCentral {
public Button rtnBtn;
// button to return to Game Central at any point when clicked
public void init() {
rtnBtn = (Button)findViewById(R.id.returnBtn);
rtnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent homeScreen = new Intent(Task3Activity.this, GameCentral.class);
startActivity(homeScreen);
}
});
}
String value;
int attempts = 0;
final int maxAttempts = 1;
Random randGen = new Random();
int ranNum;
private SoundPlayer sound;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task3_layout);
init();
Bundle extras = getIntent().getExtras();
if (extras != null) {
value = extras.getString("Value1");
if (value != null) {
TextView dataRcvd = (TextView) findViewById(R.id.playerNameEntered);
dataRcvd.setText(value );
}
}
sound = new SoundPlayer(this);
final TextView textResponse = (TextView) findViewById(R.id.txtResponse);
final TextView guessText = (TextView) findViewById(R.id.txtAnswer);
final EditText userGuess = (EditText) findViewById(R.id.etNumber);
Button pressMe = (Button) findViewById(R.id.btnGuess);
final Button rtnButton = (Button) findViewById(R.id.returnBtn);
int min = 1;
int max = 19;
randGen = new Random();
// Generate number once
ranNum = randGen.nextInt(max - min + 1) + min;
final Toast toast = Toast.makeText(getApplicationContext(), "Please guess between 0 and 20", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 350);
// When the button is clicked, it shows the text assigned to the txtResponse TextView box
pressMe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean correct = false;
final AlertDialog.Builder alert = new AlertDialog.Builder(Task3Activity.this);
alert.setTitle("Unlucky");
alert.setCancelable(false);
alert.setMessage("You have guessed incorrectly three times. " +
"The answer was " + ranNum + ". " + "Would you like to play again?")
//.setCancelable(true)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//dialog.dismiss();
Intent i = new Intent(Task3Activity.this, Task3Activity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
alert
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
//Task1Activity.this.finish();
dialog.dismiss();
//finishAffinity();
Intent toy = new Intent(Task3Activity.this, GameCentral.class);
startActivity(toy);
}
;
});
final AlertDialog.Builder alert2 = new AlertDialog.Builder(Task3Activity.this);
alert2.setTitle("You Did It!");
alert2.setCancelable(false);
alert2.setMessage("The answer was " + ranNum + ". " + "Would you like to play again?")
//.setCancelable(true)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//dialog.dismiss();
Intent i = new Intent(Task3Activity.this, Task3Activity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
alert2
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
//Task1Activity.this.finish();
dialog.dismiss();
Intent toy = new Intent(Task3Activity.this, GameCentral.class);
startActivity(toy);
//finishAffinity();
}
;
});
int userNumber = Integer.parseInt(userGuess.getText().toString());
if ((userNumber < 1) || (userNumber > 19)) {
//guessText.setText("Please guess between 0 and 20");
//guessText.setBackgroundColor(Color.WHITE);
toast.show();
} else if (userNumber < ranNum) {
guessText.setText("Your answer is too low. Guess again!");
guessText.setBackgroundColor(Color.YELLOW);
//sound.playBuzzerSound();
} else if (userNumber > ranNum) {
guessText.setText("Your answer is too high. Guess again!");
guessText.setBackgroundColor(Color.RED);
//sound.playBuzzerSound();
} else if (userNumber == ranNum) {
ranNum = randGen.nextInt(20);
//guessText.setText("You did it!");
//guessText.setBackgroundColor(Color.WHITE);
correct = true;
alert2.show();
sound.playApplauseSound();
}
if (attempts++ > maxAttempts && !correct) {
alert.show();
sound.playBooSound();
//guessText.setText("You have guessed incorrectly three times. The answer was " + ranNum);
} else if (correct) {
} else {
String randText = "";
randText = Integer.toString(ranNum);
textResponse.setText("");
userGuess.setText("");
}
}
}
);
}
}
Because you are not passing a Bundle in your intent, you don't need to use getIntent().getExtras();.
GameCentral:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.guessingGame:
Intent intent = new Intent(GameCentral.this, Task3Activity.class);
intent.putExtra("PlayerName", "Name");
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Task3Activity:
public class Task3Activity extends AppCompatActivity {
...
#Override
public void onCreate(Bundle savedInstanceSate) {
...
String playerName = getIntent().getStringExtra("PlayerName");
if (playerName != null) {
TextView dataRcvd = (TextView) findViewById(R.id.playerNameEntered);
dataRcvd.setText(playerName);
}
}
...
}
intent.putExtra("PlayerName", "Name"); where "Name" is the string for where you get the player's name from. You need to create the EditText object within the scope of the Activity if you want to get the player's name from a text box.
if (id == R.id.guessingGame) {
startActivity(new Intent(this, Task3Activity.class));
switch (item.getItemId()) {
case R.id.playerNameEntered:
Bundle b = getIntent().getExtras();
value= b.getString("playerNameInput");
startActivity(this, Task3Activity.class).putExtra("playerNameInput", value);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In my case, I use bundle to get string in onOptionsItemSelected function evertime.
To active this, should send data(playerNameInput) when you change activity everytime.

Handler doesn't stop on button click

I have a runnable which starts an activity and a handler, which lets the runnable repeat after 5 seconds. However, i implemented a "stop button" which should stop that handler, but somehow it doesn't work.
I would appreciate some help why it doesn't stop the loop.
public class MainActivity extends Activity {
private Button callBtn;
private Button stopBtn;
Handler handler = new Handler();
Runnable redial=new Runnable(){
#Override public void run(){Intent callIntent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:+49888888"));startActivity(callIntent);
}};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callBtn = (Button) findViewById(R.id.call);
stopBtn = (Button) findViewById(R.id.stop);
// add PhoneStateListener for monitoring
MyPhoneListener phoneListener = new MyPhoneListener();
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// receive notifications of telephony state changes
telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
callBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
redial.run();
}
});
stopBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
handler.removeCallbacks(redial);
}
});
}
private class MyPhoneListener extends PhoneStateListener {
private boolean onCall = false;
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Toast.makeText(MainActivity.this, incomingNumber + " calls you",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Toast.makeText(MainActivity.this, "on call...",
Toast.LENGTH_LONG).show();
//because user answers the incoming call
onCall = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall == true) {
Toast.makeText(MainActivity.this, "restart app after call",
Toast.LENGTH_LONG).show();
// restart our application
Intent restart = getBaseContext().getPackageManager().
getLaunchIntentForPackage(getBaseContext().getPackageName());
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
handler.postDelayed(redial, 5000);
}
break;
default:
break;
}
}
}

Android Quiz Game - Countdown timer for each qstion

I have created a Quiz app for Android using the tutorial here: http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html
For each question, the user will only have 20 seconds to answer it. If he/she fails to answer in 20 seconds, an AlertDialog will popup and the game will terminate.
To do this, I have added a counter in the OnCreate method of QuestionActivity class:
final TextView myCounter = (TextView) findViewById(R.id.countdown);
new CountDownTimer(20000, 1000) {
#Override
public void onFinish() {
timeUp();
}
#Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
public void timeUp() {
AlertDialog.Builder builder = new AlertDialog.Builder(
QuestionActivity.this);
builder.setTitle("Times up!")
.setMessage("Game over")
.setCancelable(false)
.setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
QuestionActivity.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
The counter works displays and functions on screen correctly. After answering a question, the activity moves to the next question and the counter resets itself to 20 seconds again.
The problem
The quiz has 15 questions, after answering 3 or 4 questions, the app crashes and I get the following error:
07-18 00:49:05.530: E/AndroidRuntime(4867): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#41533a80 is not valid; is your activity running?
I believe this relates to the AlertDialog. I have looked up this error code on Stackoverflow and the popular solution is to pass ActivityName.this as the context when building the AlertDialog.
Unfortunately this does not solve the problem.
I believe the counter is setting a time limit of 20 seconds for the whole activity. My requirement is 20 seconds for each question.
However, the counter resets to 20 seconds when the user press the' Next button and the activity moves to the next question.
Should I be resetting the counter when the user presses the Next button? Here is the OnClickListener code for the Next button
if (currentGame.isGameOver()) {
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
} else {
Intent i = new Intent(this, QuestionActivity.class);
startActivity(i);
SHOULD I ADD SOMETHING HERE?
finish();
Can anyone help me code a solution to my problem?
Here is all the code in QuestionActivity.class
public class QuestionActivity extends SherlockActivity implements
OnClickListener {
private Question currentQ;
private GamePlay currentGame;
private Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
getSupportActionBar().hide();
/**
* Configure current game and get question
*/
currentGame = ((ChuckApplication) getApplication()).getCurrentGame();
currentQ = currentGame.getNextQuestion();
Button nextBtn = (Button) findViewById(R.id.nextBtn);
nextBtn.setOnClickListener(this);
Button quitBtn = (Button) findViewById(R.id.quitBtn);
quitBtn.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
finish();
}
});
//Update the question and answer options..
setQuestions();
final TextView myCounter = (TextView) findViewById(R.id.countdown);
new CountDownTimer(20000, 1000) {
#Override
public void onFinish() {
// myCounter.setText("Time up!");
timeUp(context);
}
#Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
}
public void timeUp(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(
QuestionActivity.this);
builder.setTitle("Times up!")
.setMessage("Game over")
.setCancelable(false)
.setNeutralButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
QuestionActivity.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
/**
* Method to set the text for the question and answers from the current
* games current question
*/
private void setQuestions() {
// set the question text from current question
String question = Utility.capitalise(currentQ.getQuestion()) + "?";
TextView qText = (TextView) findViewById(R.id.question);
qText.setText(question);
// set the available options
List<String> answers = currentQ.getQuestionOptions();
TextView option1 = (TextView) findViewById(R.id.answer1);
option1.setText(Utility.capitalise(answers.get(0)));
TextView option2 = (TextView) findViewById(R.id.answer2);
option2.setText(Utility.capitalise(answers.get(1)));
TextView option3 = (TextView) findViewById(R.id.answer3);
option3.setText(Utility.capitalise(answers.get(2)));
TextView option4 = (TextView) findViewById(R.id.answer4);
option4.setText(Utility.capitalise(answers.get(3)));
}
public void onClick(View arg0) {
//validate a checkbox has been selected
if (!checkAnswer())
return;
//check if end of game
if (currentGame.isGameOver()) {
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
} else {
Intent i = new Intent(this, QuestionActivity.class);
startActivity(i);
finish();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Check if a checkbox has been selected, and if it has then check if its
* correct and update gamescore
*/
private boolean checkAnswer() {
String answer = getSelectedAnswer();
if (answer == null) {
// Log.d("Questions", "No Checkbox selection made - returning");
return false;
} else {
// Log.d("Questions",
// "Valid Checkbox selection made - check if correct");
if (currentQ.getAnswer().equalsIgnoreCase(answer)) {
// Log.d("Questions", "Correct Answer!");
currentGame.incrementRightAnswers();
} else {
// Log.d("Questions", "Incorrect Answer!");
currentGame.incrementWrongAnswers();
}
return true;
}
}
private String getSelectedAnswer() {
RadioButton c1 = (RadioButton) findViewById(R.id.answer1);
RadioButton c2 = (RadioButton) findViewById(R.id.answer2);
RadioButton c3 = (RadioButton) findViewById(R.id.answer3);
RadioButton c4 = (RadioButton) findViewById(R.id.answer4);
if (c1.isChecked()) {
return c1.getText().toString();
}
if (c2.isChecked()) {
return c2.getText().toString();
}
if (c3.isChecked()) {
return c3.getText().toString();
}
if (c4.isChecked()) {
return c4.getText().toString();
}
return null;
}
I think the activity doesn't exist anymore at a certain point when you try to make the dialog(probably when the CountDownTimer is near the end?!?).
Anyway I think finishing and starting the same activity for each question isn't such a good idea, instead you could use the current activity and simply restart the timer. For example:
public class QuestionActivity extends SherlockActivity implements
OnClickListener {
private CountDownTimer mCountDown;
#Override
public void onCreate(Bundle savedInstanceState) {
// ...
mCountDown = new CountDownTimer(20000, 1000) {
#Override
public void onFinish() {
// myCounter.setText("Time up!");
timeUp(context);
}
#Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
// ...
and in the onClick callback do the same to setup a new question, stop the old timer and restart the new timer:
//check if end of game
if (currentGame.isGameOver()) {
Intent i = new Intent(this, EndgameActivity.class);
startActivity(i);
finish();
} else {
if (mCountDown != null) {
mCountDown.cancel();
}
currentQ = currentGame.getNextQuestion();
setQuestions();
mCountDown = new CountDownTimer(20000, 1000) {
#Override
public void onFinish() {
// myCounter.setText("Time up!");
timeUp(context);
}
#Override
public void onTick(long millisUntilFinished) {
myCounter.setText("Time left: "
+ String.valueOf(millisUntilFinished / 1000));
}
}.start();
}
Also, in the callback for the Dialog's Button I would first close the Dialog before finishing the Activity:
((AlertDialog) dialog).dismiss();
QuestionActivity.this.finish();

Categories

Resources