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);
}
}
|