title: Android Quiz Game - Countdown timer for each qstion
body: <p>I have created a Quiz app for Android using the tutorial here: <a href="http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html" rel="nofollow">http://automateddeveloper.blogspot.co.uk/2011/06/getting-started-complete-android-app.html</a></p>
  
  <p>For each question, the user will only have 20 seconds to answer it. If he/she fails to answer in 20 seconds, an <code>AlertDialog</code> will popup and the game will terminate.</p>
  
  <p>To do this, I have added a counter in the <code>OnCreate</code> method of <code>QuestionActivity class</code>:</p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>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.</p>
  
  <p><strong>The problem</strong> </p>
  
  <p>The quiz has 15 questions, after answering 3 or 4 questions, the app crashes and I get the following error:</p>
  
  <pre><code>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?
  </code></pre>
  
  <p>I believe this relates to the <code>AlertDialog</code>. I have looked up this error code on Stackoverflow and the popular solution is to pass <code>ActivityName.this</code> as the context when building the <code>AlertDialog</code>. </p>
  
  <p>Unfortunately this does not solve the problem.</p>
  
  <p>I believe the counter is setting a time limit of 20 seconds for the whole activity. My requirement is 20 seconds for each question. </p>
  
  <p>However, the counter resets to 20 seconds when the user press the' <code>Next</code> button and the activity moves to the next question.</p>
  
  <p>Should I be resetting the counter when the user presses the <code>Next</code> button? Here is the <code>OnClickListener</code> code for the <code>Next</code> button</p>
  
  <pre><code>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();
  </code></pre>
  
  <p><strong>Can anyone help me code a solution to my problem?</strong></p>
  
  <p>Here is all the code in <code>QuestionActivity.class</code></p>
  
  <pre><code>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&lt;String&gt; 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;
  }
  </code></pre>