Learn.java :  » Tools » anxt » com » edcampion » anxtiterationone » Android Open Source

Android Open Source » Tools » anxt 
anxt » com » edcampion » anxtiterationone » Learn.java
package com.edcampion.anxtiterationone;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This class implements the Learn functionality of the app. To do this it
 * extracts question data from the Database, this data is displayed to the user
 * using a UI specified in mainLearn.xml. Widgets on the UI are instantiated so
 * that they may be modified(text set) and input collected.
 * 
 * @author Ed
 * 
 */
public class Learn extends Activity implements OnClickListener {
  // Widgets
  TextView questionNum;
  TextView question;
  TextView answer1;
  TextView answer2;
  TextView answer3;
  TextView answer4;
  TextView scoreLabel;
  Button nextActivity;
  Button nextQ;
  Button prevQ;
  Button menuBtn;

  Button answerOneBtn;
  Button answerTwoBtn;
  Button answerThreeBtn;
  Button answerFourBtn;

  /**
   * Reference to the Database handling class,this class implements the
   * singleton pattern, hence constructor not called directly.
   */
  protected DBAdapter db = DBAdapter.GetDBAdapterReference(this);

  /**
   * Used to store results of database queries
   */
  // protected Cursor qCursorCurrent;
  static final int QTOTAL = 10;
  static final int SCOREINC = 10;
  int currentQ = 0;
  /**
   *Array to hold the ids of questions which have been asked.
   */
  protected int[] askedQIds = new int[QTOTAL];

  /**
   * Array list to hold the ids of questions that were answered incorrectly.
   */
  protected ArrayList<Integer> incorrectQIds;
  int numAskedQs = 0;
  int playerScore = 0;
  int playerAnswer = 0;
  /**
   * Array to hold the players answers.
   */
  protected int[] playerAnswersArr = new int[QTOTAL];

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainlearn);
    CreateWidgets();
    incorrectQIds = new ArrayList<Integer>();
    db.createDatabaseFromFile();// read in the existing database(done once)

    GetNewQuestion();// get the first question.

  }

  @Override
  public void onClick(View v) {
    AnxtMain.myVib.vibrate(50);// vibrate to tell the user that button press
    // has been recognized.
    if (v.getId() == R.id.menuButton) {
      Intent myIntent = new Intent(v.getContext(), AnxtMain.class);
      // qCursorCurrent.close();
      finish();// close the current activity
      startActivityForResult(myIntent, 0);

    }

    else if (v.getId() == R.id.answerButton1
        || v.getId() == R.id.answerButton2
        || v.getId() == R.id.answerButton3
        || v.getId() == R.id.answerButton4) {
      AnswerQuestion(v.getId());
    }

    else if (v.getId() == R.id.nextQButton) {
      HandleNextButton();

    }

    else if (v.getId() == R.id.prevQButton) {
      // HandlePreviousButton();
    }

  }

  /**
   * Method to handle a next button press. The method controls if a new
   * question will be loaded in, and prevents the user from getting a new
   * question without answering the current one.
   */
  protected void HandleNextButton() {
    if (numAskedQs < QTOTAL) {

      if (playerAnswer != 0) {
        GetNewQuestion();
        questionNum.setText("Question " + Integer.toString(currentQ)
            + " / " + Integer.toString(QTOTAL));
      } else if (playerAnswer == 0) {
        CharSequence text = "Please answer the current question before moving on";
        int duration = Toast.LENGTH_SHORT;

        Toast toast = Toast.makeText(this, text, duration);
        toast.show();
      }

    }

    else
      Educate();// all of the prescribed questions have been asked, now
    // show the results.
  }

  /**
   * Method to handle creation of all of the widgets necessary for the Learn
   * activity.
   */
  protected void CreateWidgets() {
    // create widgets
    question = (TextView) findViewById(R.id.questionText);
    questionNum = (TextView) findViewById(R.id.qNumTextView);

    questionNum.setText("Question " + Integer.toString(numAskedQs + 1)
        + " / " + Integer.toString(QTOTAL));

    answer1 = (TextView) findViewById(R.id.ansNum1);
    answer2 = (TextView) findViewById(R.id.ansNum2);
    answer3 = (TextView) findViewById(R.id.ansNum3);
    answer4 = (TextView) findViewById(R.id.ansNum4);
    scoreLabel = (TextView) findViewById(R.id.scoreLabel);
    scoreLabel.setText("Score: " + Integer.toString(playerScore));

    nextQ = (Button) findViewById(R.id.nextQButton);
    prevQ = (Button) findViewById(R.id.prevQButton);
    menuBtn = (Button) findViewById(R.id.menuButton);
    answerOneBtn = (Button) findViewById(R.id.answerButton1);
    answerTwoBtn = (Button) findViewById(R.id.answerButton2);
    answerThreeBtn = (Button) findViewById(R.id.answerButton3);
    answerFourBtn = (Button) findViewById(R.id.answerButton4);

    answerOneBtn.setOnClickListener(this);
    answerTwoBtn.setOnClickListener(this);
    answerThreeBtn.setOnClickListener(this);
    answerFourBtn.setOnClickListener(this);
    menuBtn.setOnClickListener(this);
    nextQ.setOnClickListener(this);
    prevQ.setOnClickListener(this);

  }

  /**
   * Method to handle starting the Educate activity,Learn handles the
   * questioning process. Displaying the results is quite different so another
   * activity is used. The array of player answers, the array of asked
   * question ids and the arraylist of ids of incorrectly answered questions
   * are sent to the Educate activity.
   */
  protected void Educate() {
    Intent myIntent = new Intent(this, Educate.class);
    // Set up a bundle to hold the data we want to send to the Educate
    // activity.
    Bundle educateBundle = new Bundle();
    educateBundle.putIntArray("playerAnsArrI", playerAnswersArr);
    educateBundle.putIntArray("askedQsArrI", askedQIds);
    educateBundle.putIntegerArrayList("incorrectQsArListI", incorrectQIds);
    myIntent.putExtras(educateBundle);
    // qCursorCurrent.deactivate();
    setResult(RESULT_OK);
    finish();
    startActivityForResult(myIntent, 0);

  }

  /**
   * Method to allow the user to answer questions. The method checks if the
   * answer was correct,increments player score if it was, and stores the id
   * of the question if not.
   * 
   * @param viewId
   *            the id of the button that was pushed.
   */
  protected void AnswerQuestion(int viewId) {
    boolean correct = false;

    if (playerAnswer == 0) {
      if (viewId == R.id.answerButton1) {
        playerAnswer = 1;
      }

      if (viewId == R.id.answerButton2) {
        playerAnswer = 2;
      }
      if (viewId == R.id.answerButton3) {
        playerAnswer = 3;
      }
      if (viewId == R.id.answerButton4) {
        playerAnswer = 4;
      }

      playerAnswersArr[(currentQ - 1)] = playerAnswer;
      Cursor checkAnsCursor = null;
      int answer = -1;

      try {
        db.open();
        checkAnsCursor = db.getEntryById(askedQIds[(currentQ - 1)]);
        // startManagingCursor(checkAnsCursor);
        // db.close();

        int ansIndex = 0;
        ansIndex = checkAnsCursor.getColumnIndex(this // retrieve the
            // index
            // of the correct
            // answer
            .getString(R.string.KEY_TRUEANSWER));

        answer = checkAnsCursor.getInt(ansIndex); // use the index to
      } catch (Exception ex) {
        Log.w("ANSWER_QUESTION", "Failed to dispose of checkAnsCursor",
            ex);
      }

      finally {
        if (checkAnsCursor != null) {
          checkAnsCursor.close();
        }
        if (db.isOpen() == true) {
          db.close();
        }
      }
      // retrieve the
      // correct answer

      if (playerAnswer == answer) {
        playerScore += 10;
        correct = true;
      } else {
        correct = false;
        // store the id of the incorrectly answered question
        incorrectQIds.add(askedQIds[(currentQ - 1)]);
      }

      scoreLabel.setText("Score: " + Integer.toString(playerScore));// update
      // the
      // score
      // label
      ShowRightWrongToast(correct);
    }

  }

  /**
   * Method to provide right wrong feedback after the player answers a
   * question.
   * 
   * @param correct
   *            holds if the answer was answered correctly or not.
   */
  protected void ShowRightWrongToast(boolean correct) {
    CharSequence text;
    if (correct == true) {
      text = "Correct! Your score is now: "
          + Integer.toString(playerScore);
    } else {
      text = "Incorrect: "
          + "The correct answer will be shown "
          + "at the end of this test."
          + " Please push the next button to move to the next question";

    }

    Toast toast = Toast.makeText(this, text, 0);
    toast.setDuration(200);
    toast.show();
  }

  /**
   * Method to retrieve a new question from the Database. The question's id is
   * passed to CheckAskedAlready to see if it has been asked already, if it
   * hasn't the id is added to the array list of asked questions,the question
   * is then passed to FillQuestion which displays the question data on the
   * UI. Then the currentQ counter and number of questions asked counter are
   * incremented.
   */
  protected void GetNewQuestion() {
    boolean askedAlready = false;

    /*
     * Previous Button unneccessary: if the user has used the previous
     * button, when they use the next button they expect to see the question
     * they were on before they used the previous button.
     * 
     * The if statement check if the previous button has been used: # A
     * record is kept of how many questions have been asked, if the current
     * question is less than this number, then the previous button has been
     * used. #--A record is also kept of the ids of the questions that have
     * been asked.Because arrays are zero based and currentQ is not,
     * currentQ can be used as the index to get the appropriate next
     * question. #--The currentQ is then updated.
     */
    // if (currentQ < numAskedQs) {
    // db.open();
    // qCursorCurrent = db.getEntryById(askedQIds[currentQ]);
    // db.close();
    // FillQuestion(qCursorCurrent);
    // currentQ++;

    // }

    // else {
    Cursor nextQuestionCursor = null;
    try {
      db.open();
      nextQuestionCursor = db.getRandomEntry();
      // startManagingCursor(nextQuestionCursor);
      // db.close();
      /*
       * loop through the questions asked so far, check if the id is in
       * the array of asked ids, if it is mark it as asked, if it isnt add
       * it's ids to the array of asked qs, Show the question, increment
       * the currentQ counter.
       */

      int idIndex = nextQuestionCursor.getColumnIndex(this
          .getString(R.string.KEY_ROWID));

      int id = nextQuestionCursor.getInt(idIndex);

      CheckAskedAlready(id, askedAlready);// check if the
      // id is in the
      // array of asked qd ids

      while (askedAlready == true)// if it has been asked already, keep
      // pulling random questions
      // from the DB until we get one we havent asked before.
      {
        // db.open();
        nextQuestionCursor = db.getRandomEntry();
        // db.close();
        idIndex = nextQuestionCursor.getColumnIndex(this
            .getString(R.string.KEY_ROWID));
        id = nextQuestionCursor.getInt(idIndex);
        CheckAskedAlready(id, askedAlready);

      }

      // if we havent asked the question
      // add its id to the array of asked qs
      // call the method to show the
      // question fields on the UI
      // increment the current question counter
      // increment the total questions asked counter
      if (askedAlready == false) {
        // before
        askedQIds[currentQ] = nextQuestionCursor.getInt(idIndex);
        FillQuestion(nextQuestionCursor);

        currentQ++;
        numAskedQs++;
        // qCursorCurrent.deactivate();
        // nextQuestionCursor.close();
      }
    }

    catch (Exception ex) {
      Log.w("GET_QUESTION", "Failed to dispose of nextQCursor", ex);
    } finally {
      if (nextQuestionCursor != null) {
        nextQuestionCursor.close();
      }

      if (db.isOpen() == true) {
        db.close();
      }
    }
    // }
    playerAnswer = 0;// when a new question is got reset the players answer.
  }

  /**
   * Method to check if the question extracted from the Database has been
   * asked in the current session. the array of asked question ids is looped
   * through.If the passed in id is in the array of asked question ids, then
   * it has been asked before.
   * 
   * @param pId
   *            the id of the current question.
   * @param pAskedAlready
   *            boolean storing if the id is in the array of asked question
   *            ids.
   */
  protected void CheckAskedAlready(int pId, boolean pAskedAlready) {
    for (int i = 0; i < numAskedQs; i++) {
      if (askedQIds[i] == pId) {
        pAskedAlready = true;
        break;// id found no need to loop further
      } else
        pAskedAlready = false;
    }
  }

  /**
   * Method to display the question data on the UI. The index for each of the
   * columns is retrieved and this is then used to extract the data from the
   * cursor.This data is then displayed on the appropriate UI field.
   * 
   * @param qCursor
   *            the cursor containing the question data retrieved from the
   *            database.
   */
  protected void FillQuestion(Cursor qCursor) {

    int questionIndex = qCursor.getColumnIndex(this
        .getString(R.string.KEY_QUESTION));
    String questionText = qCursor.getString(questionIndex);
    question.setText(questionText);

    int possAns1Index = qCursor.getColumnIndex(this
        .getString(R.string.KEY_ANSONE));
    String possAns1Text = qCursor.getString(possAns1Index);
    answer1.setText("1. " + possAns1Text);

    int possAns2Index = qCursor.getColumnIndex(this
        .getString(R.string.KEY_ANSTWO));
    String possAns2Text = qCursor.getString(possAns2Index);
    answer2.setText("2. " + possAns2Text);

    int possAns3Index = qCursor.getColumnIndex(this
        .getString(R.string.KEY_ANSTHREE));
    String possAns3Text = qCursor.getString(possAns3Index);
    answer3.setText("3. " + possAns3Text);

    int possAns4Index = qCursor.getColumnIndex(this
        .getString(R.string.KEY_ANSFOUR));
    String possAns4Text = qCursor.getString(possAns4Index);
    answer4.setText("4. " + possAns4Text);

  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.