I need to hide a radio button in a quiz app android - java

I would like to ask for some help with my android code. I am trying to develop a quiz app using SQLite.Number of possible answers differs so i need to hide radio buttons from the main screen if answers e.g. are 3 and not 4 (4 is by default the number of the radio buttons). Tried to use:
if (DataContract.QuestionTable.COLUMN_ANSWER4.isEmpty ()){ radioButton4.setVisibility (View.INVISIBLE); }
but does not seem to work.I'm new in android programming and this is my first project so every comment will be very helpful. Thank you.

Here's a demo with a suggested technique, considering the limited amount of code posted with the question.
This utilises two tables to conform with a normalised approach. A table for the questions and a table for answers. Each answer (the Children) has a link/map/relationship/association with a single Question (the Parent). To prevent referential integrity issues a Foreign Key constraint has been used.
First a few POJO's for the Questions, the Answers and QuestionWithAnswers (i.e. it's answers)
QuestionPOJO
class QuestionPOJO {
long questionId;
String questionText;
public QuestionPOJO(long questionId, String questionText) {
this.questionId = questionId;
this.questionText = questionText;
}
public long getQuestionId() {
return questionId;
}
public void setQuestionId(long questionId) {
this.questionId = questionId;
}
public String getQuestionText() {
return questionText;
}
public void setQuestionText(String questionText) {
this.questionText = questionText;
}
}
AnswerPOJO
class AnswerPOJO {
long answerId;
long questionMap;
String answerText;
boolean correct = false;
public AnswerPOJO(long answerid, long questionMap, String answerText, boolean correct) {
this.answerId = answerid;
this.questionMap = questionMap;
this.answerText = answerText;
this.correct = correct;
}
public long getAnswerId() {
return answerId;
}
public void setAnswerId(long answerId) {
this.answerId = answerId;
}
public long getQuestionMap() {
return questionMap;
}
public void setQuestionMap(long questionMap) {
this.questionMap = questionMap;
}
public boolean isCorrect() {
return correct;
}
public void setCorrect(boolean correct) {
this.correct = correct;
}
public String getAnswerText() {
return answerText;
}
public void setAnswerText(String answerText) {
this.answerText = answerText;
}
}
and QuestionWithAnswerPOJO
class QuestionWithAnswersPOJO {
QuestionPOJO question;
ArrayList<AnswerPOJO> answers = new ArrayList<>();
public QuestionWithAnswersPOJO(QuestionPOJO question, List<AnswerPOJO> answers) {
this.question = question;
this.answers.clear();
this.answers.addAll(answers);
}
public QuestionPOJO getQuestion() {
return question;
}
public void setQuestion(QuestionPOJO question) {
this.question = question;
}
public ArrayList<AnswerPOJO> getAnswers() {
return answers;
}
public void setAnswers(ArrayList<AnswerPOJO> answers) {
this.answers = answers;
}
}
Now the DatabaseHelper, that handles all the database activity. Including methods to add and get Questions and the Answers and notably to get the Answers that belong to a question.
class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "questions.db";
public static final int DATABASE_VERSION = 1;
public static final String QUESTION_TABLE = "question";
public static final String QUESTION_ID_COLUMN = BaseColumns._ID;
public static final String QUESTION_TEXT_COLUMN = "question_text";
public static final String ANSWER_TABLE = "answer";
public static final String ANSWER_ID_COLUMN = BaseColumns._ID;
public static final String ANSWER_TEXT_COLUMN = "answer_text";
public static final String ANSWER_QUESTION_MAP_COLUMN = "question_map";
public static final String ANSWER_CORRECT_COLUMN = "correct";
private static volatile DatabaseHelper instance = null;
private DatabaseHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
private static SQLiteDatabase db = null;
public static DatabaseHelper getInstance(Context context, boolean forceOpen) {
if (instance == null) {
instance = new DatabaseHelper(context);
}
if (forceOpen) {
db = instance.getWritableDatabase();
}
return instance;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + QUESTION_TABLE + "(" +
QUESTION_ID_COLUMN + " INTEGER PRIMARY KEY," +
QUESTION_TEXT_COLUMN + " TEXT" +
");");
db.execSQL("CREATE TABLE IF NOT EXISTS " + ANSWER_TABLE + "(" +
ANSWER_ID_COLUMN + " INTEGER PRIMARY KEY," +
ANSWER_TEXT_COLUMN + " TEXT," +
ANSWER_QUESTION_MAP_COLUMN + " INTEGER REFERENCES " + QUESTION_TABLE + "(" + QUESTION_ID_COLUMN + ") ON DELETE CASCADE ON UPDATE CASCADE," +
ANSWER_CORRECT_COLUMN + " INTEGER DEFAULT 0 /* false */" +
");");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
// Fully comprehensive Question insert
public long insertQuestion(Long questionId, String questionText) {
init_db_AsWriteableDatabase();
long rv = -2;
ContentValues cv = new ContentValues();
if (questionId != null && questionId > 0) {
cv.put(QUESTION_ID_COLUMN,questionId);
}
if (questionText != null && questionText.length() > 0) {
cv.put(QUESTION_TEXT_COLUMN,questionText);
}
if (cv.size() > 0) {
rv = db.insert(QUESTION_TABLE,null,cv);
}
return rv;
}
// Concise Question insert
public long insertQuestion(String questionText) {
return insertQuestion(null,questionText);
}
// Fully comprehensive Answer insert
public long insertAnswer(Long answerId, long questionMap, String answerText, boolean correct) {
init_db_AsWriteableDatabase();
long rv = -2;
ContentValues cv = new ContentValues();
if (answerId != null && answerId > 0) {
cv.put(ANSWER_ID_COLUMN,answerId);
}
if (answerText != null && answerText.length() > 0) {
cv.put(ANSWER_CORRECT_COLUMN,correct);
cv.put(ANSWER_TEXT_COLUMN,answerText);
cv.put(ANSWER_QUESTION_MAP_COLUMN,questionMap);
rv = db.insert(ANSWER_TABLE,null,cv);
}
return rv;
}
// long concise Answer insert
public long insertAnswer(long questionMap, String answerText, boolean correct) {
return insertAnswer(null,questionMap,answerText,correct);
}
public long insertAnswer(long questionMap, String answerText) {
return insertAnswer(questionMap,answerText,false);
}
// short concise Answer insert
private void init_db_AsWriteableDatabase() {
if (db == null) {
db = this.getWritableDatabase();
}
}
#SuppressLint("Range")
public QuestionPOJO getQuestionById(long questionId) {
QuestionPOJO rv = null;
init_db_AsWriteableDatabase();
Cursor csr = db.query(QUESTION_TABLE,null,QUESTION_ID_COLUMN+"=?",new String[]{String.valueOf(questionId)},null,null,null);
if (csr.moveToNext()) {
rv = new QuestionPOJO(csr.getLong(csr.getColumnIndex(QUESTION_ID_COLUMN)),csr.getString(csr.getColumnIndex(QUESTION_TEXT_COLUMN)));
}
csr.close();
return rv;
}
#SuppressLint("Range")
public List<AnswerPOJO> getAnswersForQuestion(long questionId, boolean onlyCorrect) {
init_db_AsWriteableDatabase();
ArrayList<AnswerPOJO> rv = new ArrayList<>();
StringBuilder whereClause = new StringBuilder();
whereClause.append(ANSWER_QUESTION_MAP_COLUMN + "=?");
if (onlyCorrect) {
whereClause.append(" AND ").append(ANSWER_CORRECT_COLUMN);
}
Cursor csr = db.query(ANSWER_TABLE,null,whereClause.toString(),new String[]{String.valueOf(questionId)},null,null,null);
while (csr.moveToNext()) {
rv.add(
new AnswerPOJO(
csr.getLong(csr.getColumnIndex(ANSWER_ID_COLUMN)),
questionId,
csr.getString(csr.getColumnIndex(ANSWER_TEXT_COLUMN)),
csr.getInt(csr.getColumnIndex(ANSWER_CORRECT_COLUMN)) > 0
)
);
}
csr.close();
return rv;
}
}
Finally to put it all together and activity that has a layout for 4 radio buttons along with the associated answer as a TextView.
So the layout is:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!">
</TextView>
<RadioGroup
android:id="#+id/question_radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="#+id/answer1_radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="DuplicateSpeakableTextCheck"></RadioButton>
<TextView
android:id="#+id/answer1_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<RadioButton
android:id="#+id/answer2_radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioButton>
<TextView
android:id="#+id/answer2_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<RadioButton
android:id="#+id/answer3_radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioButton>
<TextView
android:id="#+id/answer3_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<RadioButton
android:id="#+id/answer4_radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioButton>
<TextView
android:id="#+id/answer4_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</RadioGroup>
</LinearLayout>
simple enough to show how hiding the buttons depending upon the number of answers (or a limit according to the number of Buttons/Textviews)
And the activity to demonstrate:-
public class MainActivity extends AppCompatActivity {
DatabaseHelper dbHelper;
RadioButton[] radiobuttons = new RadioButton[4];
TextView[] answerTexts = new TextView[4];
QuestionWithAnswersPOJO currentQuestionWithAnswers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
prepare Radion Buttons and associated TextViews
*/
radiobuttons[0] = this.findViewById(R.id.answer1_radioButton);
radiobuttons[1] = this.findViewById(R.id.answer2_radioButton);
radiobuttons[2] = this.findViewById(R.id.answer3_radioButton);
radiobuttons[3] = this.findViewById(R.id.answer4_radioButton);
answerTexts[0] = this.findViewById(R.id.answer1_textview);
answerTexts[1] = this.findViewById(R.id.answer2_textview);
answerTexts[2] = this.findViewById(R.id.answer3_textview);
answerTexts[3] = this.findViewById(R.id.answer4_textview);
/*
Prepare to use Database
*/
dbHelper = DatabaseHelper.getInstance(this,true);
SQLiteDatabase db = dbHelper.getWritableDatabase();
/* Clear any existing data for consistent results */
db.delete(DatabaseHelper.ANSWER_TABLE,null,null);
db.delete(DatabaseHelper.QUESTION_TABLE,null,null);
/* Add some demo data 1 question with 5 answers (comment out to reduce number of answers)*/
long q1id = dbHelper.insertQuestion("What is 1 + 1");
dbHelper.insertAnswer(q1id,"It is 1");
dbHelper.insertAnswer(q1id,"it is 2", true);
dbHelper.insertAnswer(q1id,"It is 3");
dbHelper.insertAnswer(q1id,"It is 4");
dbHelper.insertAnswer(q1id,"It is something Else"); // will be ignored because only 4 radio buttons
/* Get the question with the answers, however many ot has */
currentQuestionWithAnswers = new QuestionWithAnswersPOJO(dbHelper.getQuestionById(q1id),dbHelper.getAnswersForQuestion(q1id,false));
/* setup (refresh) the radio buttons and textviews */
getAndSetRadioButtons(currentQuestionWithAnswers);
}
/*
Does as it says
*/
private void getAndSetRadioButtons(QuestionWithAnswersPOJO qwa) {
// Clear All
for (int i=0;i < radiobuttons.length; i++) {
radiobuttons[i].setVisibility(View.GONE);
answerTexts[i].setText("");
answerTexts[i].setVisibility(View.GONE);
}
/* show only the least of answers/radio buttons */
int numberToShow = radiobuttons.length;
if (qwa.answers.size() < radiobuttons.length) {
numberToShow = qwa.answers.size();
}
int i = 0;
for(AnswerPOJO a: qwa.answers) {
if (i < numberToShow) {
radiobuttons[i].setVisibility(View.VISIBLE);
answerTexts[i].setVisibility(View.VISIBLE);
answerTexts[i++].setText(a.answerText);
} else {
/* nothing more to do so early break out of the loop */
break;
}
}
}
}
Results
Result 1 - run with the 5 answers (see comments re 5th answer)
Result 2 - All bar 1 answer comment out so the question has just the 1 answer
The code used:-
long q1id = dbHelper.insertQuestion("What is 1 + 1");
dbHelper.insertAnswer(q1id,"It is 1");
//dbHelper.insertAnswer(q1id,"it is 2", true);
//dbHelper.insertAnswer(q1id,"It is 3");
//dbHelper.insertAnswer(q1id,"It is 4");
//dbHelper.insertAnswer(q1id,"It is something Else"); // will be ignored because only 4 radio buttons
The display :-
Result 3 - first and 5th answers only inserted
and so on.
Additional after code has been posted.
Additional Answer as code has now been added.
You say:-
Tried to use:
if (DataContract.QuestionTable.COLUMN_ANSWER4.isEmpty ()){ radioButton4.setVisibility (View.INVISIBLE); }
but does not seem to work.
If DataContract.QuestionTable.COLUMN_ANSWER4 were empty then would be facing more serious issues as it is the column name.
You should be checking for the contents of the column which has been retrieved from DB and placed into currentQuestion, for the question being inspected.
I believe that using (old code commented out):-
radioButton1.setText(currentQuestion.getAnswer1 ());
radioButton2.setText(currentQuestion.getAnswer2 ());
radioButton3.setText(currentQuestion.getAnswer3 ());
radioButton4.setText(currentQuestion.getAnswer4 ());
if(currentQuestion.getAnswer4() == null || currentQuestion.getAnswer4().isEmpty()) {
radioButton4.setVisibility(View.INVISIBLE);
} else {
radioButton4.setVisibility(View.VISIBLE); // just in case it is INVISIBLE
radioButton4.setText(currentQuestion.getAnswer4());
}
/*
if (DataContract.QuestionTable.COLUMN_ANSWER4.isEmpty ()){
radioButton4.setVisibility (View.INVISIBLE);
} else {
radioButton4.setText(currentQuestion.getAnswer4 ());
}
*/
Will resolve this issue. e.g. at Q3:-

Related

switch radiobox to checkbox to EditText using enum

I am creating a quiz with different question types. To call these types I would like to use Enum then a switch statement in my activity to make a specific type visible.
Here is what I have in my Question class
public class Question {
private String question;
private String option1;
private String option2;
private String option3;
private int answerNumber;
private enum type {RADIO, CHECKBOX, TEXTENTRY};
public Question(){}
public Question(String question, String option1, String option2, String option3, int answerNumber, int type) {
this.question = question;
this.option1 = option1;
this.option2 = option2;
this.option3 = option3;
this.answerNumber = answerNumber;
this.type = type; // expression expected, not sure how to approach this
}
}
I manually created my getters + setters as I receive this message if I try to generate them with Android Studio
'no fields without getter + setter where found'
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
This is what I have in my DBHelper.
private void fillQuestionsTable() {
Question q1 = new Question("1 is correct", "a", "b","c",1,0);
addQuestion(q1);
Question q2 = new Question("2 is correct", "a", "b","c",2,1);
addQuestion(q2);
Question q3 = new Question("3 is correct", "a", "b","c",3,2);
addQuestion(q3);
}
private void addQuestion(Question question){
ContentValues cv = new ContentValues();
cv.put(QuestionsTable.COLUMN_QUESTION, question.getQuestion());
cv.put(QuestionsTable.COLUMN_OPTION1, question.getOption1());
cv.put(QuestionsTable.COLUMN_OPTION2, question.getOption2());
cv.put(QuestionsTable.COLUMN_OPTION3, question.getOption3());
cv.put(QuestionsTable.COLUMN_ANSWERNUMBER, question.getAnswerNumber());
cv.put(QuestionsTable.COLUMN_TYPE, question.getType());
db.insert(QuestionsTable.TABLE_NAME,null, cv);
}
public List<Question> getAllQuestions(){
List<Question> questionList = new ArrayList <>();
db = getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM " + QuestionsTable.TABLE_NAME, null);
if (c.moveToFirst()){
do {
Question question = new Question();
question.setQuestion(c.getString(c.getColumnIndex(QuestionsTable.COLUMN_QUESTION)));
question.setOption1(c.getString(c.getColumnIndex(QuestionsTable.COLUMN_OPTION1)));
question.setOption2(c.getString(c.getColumnIndex(QuestionsTable.COLUMN_OPTION2)));
question.setOption3(c.getString(c.getColumnIndex(QuestionsTable.COLUMN_OPTION3)));
question.setAnswerNumber(c.getInt(c.getColumnIndex(QuestionsTable.COLUMN_ANSWERNUMBER)));
question.setType(c.getInt(c.getColumnIndex(QuestionsTable.COLUMN_TYPE)));
questionList.add(question);
} while (c.moveToNext());
}
c.close();
return questionList;
}
And in my activity this is what I am using to try and switch the question types
-All views set to INVISIBLE to start then methods to make them VISIBLE-
private void showNextQuestion(){
if (questionCounter < getQuestionCounter){
currentQuestion = questionList.get(questionCounter);
question.setText(currentQuestion.getQuestion());
rb1.setText(currentQuestion.getOption1());
rb2.setText(currentQuestion.getOption2());
rb3.setText(currentQuestion.getOption3());
//switch question formats
int type = (int)
question.setText(currentQuestion.getQuestion()).questionList.get.questionType;
switch (questionType) {
// seems to like questionList better in here... still not sure how to bring up the enums
case Question.RADIO:
showRadioGroup();
break;
case Question.CHECKBOX:
showCheckboxes();
break;
case Question.TEXTENTRY:
showTypeAnswer();
break;
}
questionCounter++;
The idea is to bring everything from my Array - yes? -a bit confused here-
if I use questionList which is my array can't resolve
if I use getAllQuestions in case can't resolve getAllQuestions
if I use typeAnswer or questionList in case can't resolve RADIO nor TEXTENTRY
Sorry I was trying different approaches.
Also just realized I will have a hard time trying to verify a text entry with the code as is. Working on it.
Roughly speaking when you say private enum type {RADIO, CHECKBOX, TEXTENTRY}; you can (need to) then use type like as if it were a class.
So you need an additional line to declare an object of type for it to be a memeber ( enum ??? {...} is implicitly static and final (if my limited understanding is correct)) e.g. :-
private mytype = type;
Here's some code that may help you understand how to construct (in a few ways), get and set using enums :-
public class Question {
public enum qtype {RADIO,CHECKBOX,TEXTENTRY} //<<< accessible outside perhaps prefereable
private enum altqtype {RADIO, CHECKBOX, TEXTENTRY} //<<<< Alternative if you want private (restrictive)
private String question;
private String option1;
private String option2;
private String option3;
private int answerNumber;
private long Id;
// Define members of the enum's
private qtype mytype;
private altqtype alternative_qtype;
private qtype another;
public Question(){}
public Question(
String question,
String option1,
String option2,
String option3,
int answerNumber,
int type, //<<<< pass as an int
String stype, //<<<< pass as a String
long id, //<<<< likely needed
qtype questiontype //<<<< pass as an qtype (e.g. qtype.RADIO)
) {
this.question = question;
this.option1 = option1;
this.option2 = option2;
this.option3 = option3;
this.answerNumber = answerNumber;
this.Id = id; //<<<< You may well need this to reference DB from Arraylist
// Setting enum's
this.mytype = questiontype; // set to passed value
this.alternative_qtype = altqtype.CHECKBOX; // Sets to default
// Set it accoring to the string passed
if (isValidTypeString(stype)) {
this.alternative_qtype = altqtype.valueOf(stype);
}
this.another = convertIntToQtype(type);
}
public qtype getMytype() {
return mytype;
}
public void setMytype(qtype mytype) {
this.mytype = mytype;
}
//Given an int convert it to a qtype
private qtype convertIntToQtype(int type){
qtype rv = qtype.TEXTENTRY;
switch (type) {
case 1:
rv = qtype.RADIO;
break;
case 2:
rv = qtype.CHECKBOX;
break;
case 4:
rv = qtype.TEXTENTRY;
break;
default:
rv = qtype.TEXTENTRY;
}
return rv;
}
// Check if a given string is valid as a question type
// Note done for alternative
private boolean isValidTypeString(String pv) {
boolean rv = false;
altqtype[] typearray = altqtype.values();
for (altqtype aqt: typearray) {
if (pv.equals(aqt.toString())) {
rv = true;
break;
}
}
return rv;
}
}
Working Example
here's a working example that :-
utilises enum's
utilises both ArrayList and Cursor
ArrayList used for asking question and for List of questions (2nd)
Cursor used for List of questions (1st List)
traverses questions via PREVIOUS and NEXT buttons
Allows answer (no answer checking) to be one of Edit text, Radio Button or Checkbox according to to the question, displaying the appropriate View.
Question.java
public class Question {
public enum qtype {RADIO,CHECKBOX,TEXTENTRY} //<<< accessible outside perhaps prefereable
private enum altqtype {RADIO, CHECKBOX, TEXTENTRY} //<<<< Alternative if you want private (restrictive)
private String question;
private String option1;
private String option2;
private String option3;
private int answerNumber;
private long rowid;
// Define members of the enum's
private qtype mytype;
private altqtype alternative_qtype;
private qtype another;
public Question(){}
public Question(
String question, String option1, String option2, String option3,
int answerNumber, qtype type, long id) {
this.question = question;
this.option1 = option1;
this.option2 = option2;
this.option3 = option3;
this.answerNumber = answerNumber;
this.mytype = type;
this.rowid = id;
}
public Question(
String question, String option1, String option2, String option3,
int answerNumber, qtype type
){
this(question,option1,option2,option3,answerNumber,type,-1);
}
//<<<< Note constrcutor for demonstration of enums
public Question(
String question,
String option1,
String option2,
String option3,
int answerNumber,
int type, //<<<< pass as an int
String stype, //<<<< pass as a String
long id, //<<<< likely needed
qtype questiontype //<<<< pass as an qtype (e.g. qtype.RADIO)
) {
this.question = question;
this.option1 = option1;
this.option2 = option2;
this.option3 = option3;
this.answerNumber = answerNumber;
this.rowid = id; //<<<< You may well need this to reference DB from Arraylist
// Setting enum's
this.mytype = questiontype; // set to passed value
this.alternative_qtype = altqtype.CHECKBOX; // Sets to default
// Set it accoring to the string passed
if (isValidTypeString(stype)) {
this.alternative_qtype = altqtype.valueOf(stype);
}
this.another = convertIntToQtype(type);
}
public qtype getMytype() {
return mytype;
}
public void setMytype(qtype mytype) {
this.mytype = mytype;
}
//Given an int convert it to a qtype
private qtype convertIntToQtype(int type){
qtype rv = qtype.TEXTENTRY;
switch (type) {
case 1:
rv = qtype.RADIO;
break;
case 2:
rv = qtype.CHECKBOX;
break;
case 4:
rv = qtype.TEXTENTRY;
break;
default:
rv = qtype.TEXTENTRY;
}
return rv;
}
// Check if a given string is valid as a question type
// Note done for alternative
private static boolean isValidTypeString(String pv) {
boolean rv = false;
altqtype[] typearray = altqtype.values();
for (altqtype aqt: typearray) {
if (pv.equals(aqt.toString())) {
rv = true;
break;
}
}
return rv;
}
public static qtype convertStringToQtype(String s) {
qtype rv = qtype.TEXTENTRY; // <<<< Default
if (isValidTypeString(s)) {
rv = qtype.valueOf(s);
}
return rv;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getOption1() {
return option1;
}
public void setOption1(String option1) {
this.option1 = option1;
}
public String getOption2() {
return option2;
}
public void setOption2(String option2) {
this.option2 = option2;
}
public String getOption3() {
return option3;
}
public void setOption3(String option3) {
this.option3 = option3;
}
public int getAnswerNumber() {
return answerNumber;
}
public void setAnswerNumber(int answerNumber) {
this.answerNumber = answerNumber;
}
public long getRowid() {
return rowid;
}
public void setRowid(long rowid) {
this.rowid = rowid;
}
}
QuestionsTable.java :-
public class QuestionsTable {
public static final String TABLE_NAME = "myquestions";
public static final String COLUMN_ID = BaseColumns._ID;
public static final String COLUMN_QUESTION = "question";
public static final String COLUMN_OPTION1 = "option1";
public static final String COLUMN_OPTION2 = "option2";
public static final String COLUMN_OPTION3 = "option3";
public static final String COLUMN_ANSWERNUMBER = "answernumber";
public static final String COLUMN_TYPE = "type";
}
DBHelper.java :-
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "questions.sqlite";
public static final int DBVERSION = 1;
SQLiteDatabase db;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " +
QuestionsTable.TABLE_NAME +
"(" +
QuestionsTable.COLUMN_ID + " INTEGER PRIMARY KEY," +
QuestionsTable.COLUMN_QUESTION + " TEXT NOT NULL," +
QuestionsTable.COLUMN_OPTION1 + " TEXT NOT NULL," +
QuestionsTable.COLUMN_OPTION2 + " TEXT NOT NULL," +
QuestionsTable.COLUMN_OPTION3 + " TEXT NOT NULL," +
QuestionsTable.COLUMN_ANSWERNUMBER + " INTEGER NOT NULL," +
//<<<< NOTE will default to "TEXTENTRY"
QuestionsTable.COLUMN_TYPE + " TEXT NOT NULL DEFAULT '" +
Question.qtype.TEXTENTRY.toString() + "'" +
")";
db.execSQL(crtsql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void addQuestion(Question question){
ContentValues cv = new ContentValues();
cv.put(QuestionsTable.COLUMN_QUESTION, question.getQuestion());
cv.put(QuestionsTable.COLUMN_OPTION1, question.getOption1());
cv.put(QuestionsTable.COLUMN_OPTION2, question.getOption2());
cv.put(QuestionsTable.COLUMN_OPTION3, question.getOption3());
cv.put(QuestionsTable.COLUMN_ANSWERNUMBER, question.getAnswerNumber());
cv.put(QuestionsTable.COLUMN_TYPE, String.valueOf(question.getMytype()));
//<<<< alternative cv.put(QuestionsTable.COLUMN_TYPE,question.getMytype().toString());
db.insert(QuestionsTable.TABLE_NAME,null, cv);
}
public Cursor getQuestionsAsCursor() {
return db.query(QuestionsTable.TABLE_NAME,null,null,null,null,null,null);
}
public ArrayList<Question> getQuestionsAsArrayList() {
ArrayList<Question> rv = new ArrayList<>();
Cursor csr = db.query(QuestionsTable.TABLE_NAME,null,null,null,null,null,null);
while (csr.moveToNext()) {
rv.add(new Question(
csr.getString(csr.getColumnIndex(QuestionsTable.COLUMN_QUESTION)),
csr.getString(csr.getColumnIndex(QuestionsTable.COLUMN_OPTION1)),
csr.getString(csr.getColumnIndex(QuestionsTable.COLUMN_OPTION2)),
csr.getString(csr.getColumnIndex(QuestionsTable.COLUMN_OPTION3)),
csr.getInt(csr.getColumnIndex(QuestionsTable.COLUMN_ANSWERNUMBER)),
//<<< get the String and convert to qtype
Question.convertStringToQtype(
csr.getString(
csr.getColumnIndex(QuestionsTable.COLUMN_TYPE)
)
),
csr.getLong(csr.getColumnIndex(QuestionsTable.COLUMN_ID))
));
}
csr.close();
return rv;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
android:text="Hello World!"/>
<Button
android:id="#+id/prevquestion"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"
android:text="PREVIOUS"/>
<Button
android:id="#+id/nextquestion"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"
android:text="NEXT"/>
</LinearLayout>
<ListView
android:id="#+id/questionlist_by_cursor"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="41">
</ListView>
<ListView
android:id="#+id/questionlist_by_arraylist"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="41"
android:background="#FFDDDDFF">
</ListView>
<LinearLayout
android:orientation="horizontal"
android:id="#+id/questiondisplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="14">
<TextView
android:id="#+id/questiontext"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="wrap_content" />
<RadioButton
android:id="#+id/answerrb"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:visibility="gone"/>
<CheckBox
android:id="#+id/answercb"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:visibility="gone"/>
<EditText
android:id="#+id/answeret"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="wrap_content"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
MainActivity.java :-
public class MainActivity extends AppCompatActivity {
TextView mQuestionText;
Button mNext, mPrev;
RadioButton mRadio;
CheckBox mCheckBox;
EditText mTextEntry;
ListView mQuestionListByCursor,mQuestionListByArrayList;
DBHelper mDBHlpr;
Cursor mCsr;
SimpleCursorAdapter mSCA;
ArrayList<Question> mQuestionArrayList;
ArrayAdapter<Question> mArrayAdapter;
int mQuestionPointer = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mQuestionListByCursor = (ListView) this.findViewById(R.id.questionlist_by_cursor);
mQuestionListByArrayList = (ListView) this.findViewById(R.id.questionlist_by_arraylist);
mNext = (Button) this.findViewById(R.id.nextquestion);
mPrev = (Button) this.findViewById(R.id.prevquestion);
mRadio = (RadioButton) this.findViewById(R.id.answerrb);
mCheckBox = (CheckBox) this.findViewById(R.id.answercb);
mTextEntry = (EditText) this.findViewById(R.id.answeret);
mQuestionText = (TextView) this.findViewById(R.id.questiontext);
mDBHlpr = new DBHelper(this);
addSomeTestData(); //<<<< Add some test questions
mQuestionArrayList = mDBHlpr.getQuestionsAsArrayList(); //<<<< get the questions
refreshQuestion(); //<<<< Setup current (1st Question)
//Via Cursor
mCsr = mDBHlpr.getQuestionsAsCursor();
mSCA = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_2,
mCsr,
new String[]{QuestionsTable.COLUMN_QUESTION,QuestionsTable.COLUMN_TYPE},new int[]{android.R.id.text1,android.R.id.text2},0);
mQuestionListByCursor.setAdapter(mSCA);
//Via ArrayList
mArrayAdapter = new ArrayAdapter<Question>(
this,
android.R.layout.simple_list_item_1,mQuestionArrayList
);
mQuestionListByArrayList.setAdapter(mArrayAdapter);
mPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mQuestionPointer > 0) {
mQuestionPointer--;
refreshQuestion();
}
}
});
mNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mQuestionPointer < (mQuestionArrayList.size() -1)) {
mQuestionPointer++;
refreshQuestion();
}
}
});
}
protected void onDestroy() {
super.onDestroy();
if (!mCsr.isClosed()) {
mCsr.close();
}
}
private void addSomeTestData() {
if (DatabaseUtils.queryNumEntries(
mDBHlpr.getWritableDatabase(),
QuestionsTable.TABLE_NAME
) < 1) {
mDBHlpr.addQuestion(new Question(
"What is 1 + 1?",
"0","1","2",
2,
Question.qtype.CHECKBOX //<<<< uses shorter signature
));
mDBHlpr.addQuestion(new Question(
"What is Tom's first name?",
"Fred","Tom","Bert",
1,
Question.qtype.TEXTENTRY //<<<< uses shorter signature
));
mDBHlpr.addQuestion(new Question(
"Where is Timbuktu?",
"Afirca","Russia","Australia",
1,
Question.qtype.RADIO //<<<< uses shorter signature
));
}
}
private void refreshQuestion() {
Question q = mQuestionArrayList.get(mQuestionPointer);
mQuestionText.setText(q.getQuestion());
switch (q.getMytype()) {
case TEXTENTRY:
mTextEntry.setVisibility(View.VISIBLE);
mRadio.setVisibility(View.GONE);
mCheckBox.setVisibility(View.GONE);
break;
case RADIO:
mRadio.setVisibility(View.VISIBLE);
mCheckBox.setVisibility(View.GONE);
mTextEntry.setVisibility(View.GONE);
break;
case CHECKBOX:
mCheckBox.setVisibility(View.VISIBLE);
mRadio.setVisibility(View.GONE);
mTextEntry.setVisibility(View.GONE);
break;
}
}
}
Screen Shots :-
When first started or restart :-
Notes
the List using a Cursor via SimpleCursorAdapter (1)
the List using an ArrayList<Question) (2)
Note the toString method hasn't been overridden hence the default toString method resulting in the funny values displayed.
the current (first) question, which as per the first list can be seen to be a checkbox question (3).
Next Question (question 2) after clicking the Next button :-
EditText i.e. TEXTENTRY question
Next Question (question 3 now)
This worked as well:
In
Question.java
enum QuestionType
{RADIO,CHECKBOX, TEXTENTRY}
public class Question {
...
private QuestionType type;
public Question(String question, String option1, String option2, String option3, int answerNumber,
QuestionType type) {
...
this.type = type;
}
//generate getters and setters using the generate tool in Android Studio
public QuestionType getType() {
return type;
}
public void setType(QuestionType type) {
this.type = type;
}
}
then in
QuizDnHelper.java
#Override
public void onCreate(SQLiteDatabase db) {
this.db = db;
final String SQL_CREATE_QUESTIONS_TABLE = "CREATE TABLE " +
QuestionsTable.TABLE_NAME + " (" +
...
QuestionsTable.COLUMN_TYPE + " TEXT" + //not INTEGER!
")";
...
private void fillQuestionsTable(){
Question q1 = new Question("1 is correct", "a", "b","c",1,
QuestionType.RADIO);
private void addQuestion(Question question){
ContentValues cv = new ContentValues();
...
//set and get enum as string:
cv.put(QuestionsTable.COLUMN_TYPE, String.valueOf(question.getType()));
...
}
Cursor c = db.rawQuery("SELECT * FROM " + QuestionsTable.TABLE_NAME, null);
if (c.moveToFirst()){
do {
...
//set and get enum as string:
question.setType(QuestionType.valueOf(c.getString(c.getColumnIndex(QuestionsTable.COLUMN_TYPE))));
...
} while (c.moveToNext());
And to call this into MainActivity:
QuestionType.RADIO
....
we use enums as a class.

Updating a certain value and saving it in offline database

I'm developing a tiny app that has a value in a textview set to 150,000 by default. Each month I reset the value back to the default. Every time I spend some of that amount, I open my app and enter the amount I spent and the details of what it was spent on.
What I did was create an offline database to store all the times I spent some of that amount, along with it's id and details. Each time I press the "spend" button, the total amount is reduced by the amount I have entered in the EditText.
I haven't implemented how I'll update the total amount yet, I believe I have to use something called sharedpreference number.
This is the main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button spendMoney = (Button)this.findViewById(R.id.spendMoney);
Button test = (Button)this.findViewById(R.id.test);
TextView totalTxt = (TextView) this.findViewById(R.id.totalTxt);
final EditText spendAmount = (EditText)this.findViewById(R.id.spendAmount);
// int totalAmount = Integer.parseInt(totalTxt.getText().toString());
final Paid_DB db = new Paid_DB(this);
spendMoney.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db.addPayment(new Payment(0, (Integer.parseInt(spendAmount.getText().toString())), "Test Details"));
}
});
//totalAmount = totalAmount - Integer.parseInt(spendAmount.getText().toString());
// totalTxt.setText(totalAmount);
test.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(null, DetailsActivity.class);
startActivity(i);
}
});
XML file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.paid.MainActivity">
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="13dp"
android:layout_marginStart="13dp"
android:layout_marginTop="53dp"
android:fontFamily="sans-serif"
android:text="Total:"
android:textSize="30sp"
tools:layout_editor_absoluteX="25dp"
tools:layout_editor_absoluteY="36dp" />
<EditText
android:id="#+id/spendAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
tools:layout_editor_absoluteX="72dp"
tools:layout_editor_absoluteY="143dp"
android:layout_marginBottom="38dp"
android:layout_above="#+id/spendMoney"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/spendMoney"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Spend Money"
tools:layout_editor_absoluteX="115dp"
tools:layout_editor_absoluteY="215dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:id="#+id/totalTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView3"
android:layout_alignBottom="#+id/textView3"
android:layout_alignEnd="#+id/spendMoney"
android:layout_alignRight="#+id/spendMoney"
android:fontFamily="sans-serif"
android:text="150,000"
android:textSize="30sp"
tools:layout_editor_absoluteX="25dp"
tools:layout_editor_absoluteY="36dp" />
<Button
android:id="#+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
tools:layout_editor_absoluteX="134dp"
tools:layout_editor_absoluteY="358dp"
android:layout_marginBottom="90dp"
android:layout_alignParentBottom="true"
android:layout_alignLeft="#+id/spendMoney"
android:layout_alignStart="#+id/spendMoney" />
This is the object I enter into the offline database, containing the id, the amount spent, and details of the payment:
public class Payment {
private int id;
private int amount;
private String details;
public Payment(){}
public Payment(int id, int amount, String details) {
this.id = id;
this.amount = amount;
this.details = details;
}
public Payment(int id, int amount) {
this.id = id;
this.amount = amount;
}
public Payment(int amount, String details) {
this.amount = amount;
this.details = details;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
} }
This is the offline database:
ublic class Paid_DB extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "Payments_DB";
// Contacts table name
private static final String PAYMENT_TABLE = "PaymentTable";
// Contacts Table Columns names
private static final String PAY_ID = "id";
private static final String PAY_AMOUNT = "amount";
private static final String PAY_DETAILS = "details";
Paid_DB(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + PAYMENT_TABLE + "("
+ PAY_ID + " INTEGER PRIMARY KEY," + PAY_AMOUNT + " INTEGER,"
+ PAY_DETAILS + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + PAYMENT_TABLE);
onCreate(db);
}
public void addPayment(Payment payment){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(PAY_AMOUNT, payment.getAmount());
values.put(PAY_DETAILS, payment.getDetails()); // Contact Phone Number
// Inserting Row
db.insert(PAYMENT_TABLE, null, values);
db.close();
}
void addListItem(ArrayList<String> listItem) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
for (int i = 0; i < listItem.size(); i++) {
Log.e("vlaue inserting==", "" + listItem.get(i));
values.put(PAY_AMOUNT, listItem.get(i));
db.insert(PAYMENT_TABLE, null, values);
}
db.close(); // Closing database connection
}
Cursor getListItem() {
String selectQuery = "SELECT * FROM " + PAYMENT_TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
return cursor;
}}
And finally, this is the details activity, it contains a list view that stores and displays all the payments that have been made:
public class DetailsActivity extends AppCompatActivity {
ArrayList<String> detailsListArrayList;
private ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
lv = (ListView) findViewById(R.id.listView);
detailsListArrayList = new ArrayList<>();
detailsListArrayList.add("Item1");
detailsListArrayList.add("Item2");
detailsListArrayList.add("Item3");
detailsListArrayList.add("Item4");
detailsListArrayList.add("Item5");
Paid_DB db = new Paid_DB(this);
db.addListItem(detailsListArrayList);
Cursor cursor = db.getListItem();
Log.e("count", " " + cursor.getCount());
if (cursor != null) {
cursor.moveToNext();
do {
Log.e("value==", "" + cursor.getString(1));
} while (cursor.moveToNext());
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
detailsListArrayList );
lv.setAdapter(arrayAdapter);
}
}
XML file:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.paid.DetailsActivity">
<ListView
android:id="#+id/listView"
android:layout_width="368dp"
android:layout_height="495dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
Every time I click on the "test" button, the app crashes. And every time I try to add a new entry using the "spend" button, the app also crashes. What did I do wrong?
What I can tell from here (without the error log) is:
1) your app crashes when pressing the test-button because you are starting an activity there without passing a contextobject. Try this:
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), DetailsActivity.class);
startActivity(i);
}
2) The spend button tries to add a new payment entry to your database. But in your database schema , you declare the PAY_ID as a primary key. Later in your addPayment() you are just passing the PAY_AMOUNT and PAY_DETAILS, so you are missing the PAY_ID which seems to lead to a crash.
EDIT: something like this should return all the payments as an ArrayList (may Contain bugs, just wrote it in this editor).
public ArrayList<Payment> getAllPayments() {
ArrayList<Payment> result = new ArrayList<>();
Cursor c = db.query("PAYMENTS",new String[]{"PAY_ID","PAY_AMOUNT","PAY_DETAIL"},null,null,null,null,null); ;
c.moveToFirst();
while(! c.isAfterLast())
{
int s1=c.getInt(0);
int s2=c.getInt(1);
String s3=c.getString(2);
results.add(new Payment(s1,s2,s3));
c.moveToNext();
}
return results;
}
To update your ListView, you should have a closer look a this link, that explains how to work with ListViews and a custom ListView adapter Custom Adapter for List View

Getting error in the on create method for sqlite database

I am creating a trivia game for a class assignment. I initially wanted to store the questions with categories in a sqlite database. I'm strating with one table, though I want to add others for category, level, and users, but first wanted to get it working with just questions. The program compiles and installs into the emulator and the first part works fine. It's not until the app goes to create the database that I get an error. The error reads:
Caused by:
android.database.sqlite.SQLiteException: near "TABLEquestion": syntax error (code 1): , while compiling: CREATE TABLEquestion(questionIDINTEGER PRIMARY KEY,questionNameTEXT,optionATEXT,optionBTEXT,optionCTEXT,answerTEXT,questionLevelIDINTEGER,categoryIDINTEGER)
at android.database.sqlite
My code for the main activity, trivia question activity, question class, DBHelper class and the xml layout for the Trivia Question activity. Please note, the error occurs when the radio button is selected for a category, which launches the Trivia Question activity. (before adding the database, the launch worked without error). Also, I know I need to create methods for Updating and Deleting records, but wanted to get the database creation working first. I've looked at this for 2 days and cannot find the issue. Any assistance would be greatly appreciated.
CLASS QUESTION:
public class Question {
private Integer questionID;
private String questionName;
private String optionA;
private String optionB;
private String optionC;
private String answer;
private Integer questionLevelID;
private Integer categoryID;
public Question(){
//// TODO: 11/5/2016
}
public Question (Integer questionID, String questionName, String optionA,
String optionB, String optionC, String answer, Integer questionLevelID,
Integer catID){
this.questionID=questionID;
this.questionName=questionName;
this.optionA=optionA;
this.optionB=optionB;
this.optionC=optionC;
this.answer=answer;
this.questionLevelID=questionLevelID;
this.categoryID = catID;
}
public void setqID(Integer questionId){
this.questionID = questionId;
}
public void setqName(String questionName){
this.questionName=questionName;
}
public void setqOptA(String optionA){
this.optionA = optionA;
}
public void setqOptB(String optionB){
this.optionB = optionB;
}
public void setqOptC(String optionC){
this.optionC=optionC;
}
public void setqAns(String answer){
this.answer = answer;
}
public void setQLevel(Integer questionLevelID){
this.questionLevelID = questionLevelID;
}
public void setqcatID(Integer categoryID){
this.categoryID= categoryID;
}
public int getqID(){
return questionID;
}
public String getqName(){
return questionName;
}
public String getqOptA(){
return optionA;
}
public String getqOptB(){
return optionB;
}
public String getqOptC(){
return optionC;
}
public String getqAns(){
return answer;
}
public Integer getqLevel(){
return questionLevelID;
}
public Integer getqCatID(){
return categoryID;
}
}
MAIN ACTIVITY:
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.util.Log;
import java.util.List;
import static android.R.attr.id;
public class EduTriviaMain extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edu_trivia_main);
}
public String onCheckedChanged(View view) {
boolean checked = ((RadioButton) view).isChecked();
String category = "";
switch (view.getId()) {
case R.id.englishRadioButton:
if (checked) {
category = "english";
Intent intent = new Intent(this,TriviaQuestion.class);
startActivity(intent);
return category;
}
break;
case R.id.historyRadioButton:
if (checked) {
category = "history";
Intent intent = new Intent(this,TriviaQuestion.class);
startActivity(intent);
return category;
}
break;
case R.id.mathRadioButton:
if (checked) {
category = "math";
Intent intent = new Intent(this,TriviaQuestion.class);
startActivity(intent);
return category;
}
break;
default:
break;
}
return category;
}
}
DBHelper Class:
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
public class DBHandler extends SQLiteOpenHelper{
//Database Version
private static final int DATABASE_VERSION=1;
//Database Name
private static final String DATABASE_NAME ="eduTrivia";
//table names
private static final String TABLE_QUESTION="question";
//question table column names
private static final String KEY_QUESTIONID = "questionID";
private static final String KEY_QUESTION="questionName";
private static final String KEY_OPTIONA="optionA";
private static final String KEY_OPTIONB="optionB";
private static final String KEY_OPTIONC="optionC";
private static final String KEY_ANSWER="answer";
private static final String KEY_LEVEL = "questionLevelID";
private static final String KEY_CATEGORYID="categoryID";
private static final String CREATE_TABLE_QUESTION ="CREATE TABLE"
+ TABLE_QUESTION +"("
+ KEY_QUESTIONID +"INTEGER PRIMARY KEY,"
+ KEY_QUESTION + "TEXT,"
+ KEY_OPTIONA + "TEXT,"
+ KEY_OPTIONB + "TEXT,"
+ KEY_OPTIONC + "TEXT,"
+ KEY_ANSWER + "TEXT,"
+ KEY_LEVEL + "INTEGER,"
+ KEY_CATEGORYID + "INTEGER"+")";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_QUESTION);
addQuestions();
}
private void addQuestions(){
Question q1 = new Question(1,"How do you write this number using words? 752",
"five hudnred sixty-two","seven hundred sixty-two", "seven hundred fifty-two",
"C",1,1);
Question q2 = new Question(2,"Round 5,764,438 to the nearest hundred thousand",
"6,200,000","5,800,000","5,700,000","B",1,1);
Question q3= new Question(3,"Which equation shows the associative property of addition",
"5+4=3+6","7+(4+3)=(7+4)+3", "0+8=8","B",1,1);
Question q4 = new Question(4,"Select the adjective in this sentence: Nina is a strong worker",
"Nina","strong","worker","B",1,2);
Question q5 = new Question (5,"Select the adjective in this sentence: The twon has three banks",
"The","town","three","C",1,2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists"+TABLE_QUESTION);
onCreate(db);
}
//constructor and getInstance() method
private static DBHandler mDBHANDLER;
public static synchronized DBHandler getInstance(Context context) {
if (mDBHANDLER==null){
mDBHANDLER=new DBHandler(context.getApplicationContext());
}
return mDBHANDLER;
}
public DBHandler(Context context){
super(context, DATABASE_NAME,null,DATABASE_VERSION);
}
public void addQuestion(Question question){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_QUESTIONID,question.getqID());
values.put(KEY_QUESTION,question.getqName());
values.put(KEY_OPTIONA,question.getqOptA());
values.put(KEY_OPTIONB,question.getqOptB());
values.put(KEY_OPTIONC,question.getqOptC());
values.put(KEY_ANSWER,question.getqAns());
values.put(KEY_LEVEL,question.getqLevel());
values.put(KEY_CATEGORYID,question.getqCatID());
db.insert(TABLE_QUESTION,null,values);
db.close();
}
//reading records
public Question getQuestion(int id){
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor = db.query(TABLE_QUESTION, new String[]{
KEY_QUESTIONID, KEY_QUESTION
},KEY_QUESTIONID + "=?",
new String[]{
String.valueOf(id)},null,null,null,null);
if (cursor !=null)
cursor.moveToFirst();
Question question = new Question(Integer.parseInt(cursor.getString(0)),
cursor.getString(1),cursor.getString(2), cursor.getString(3),
cursor.getString(4),cursor.getString(5),Integer.parseInt(cursor.getString(6)),
Integer.parseInt(cursor.getString(7)));
return question;
}
public List<Question> getAllQuestions(){
//Select all questions query
List questionList = new ArrayList<Question>();
String selectAll = "SELECT * FROM "+TABLE_QUESTION;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectAll,null);
//loop through all rows and add to the list
if (cursor.moveToFirst()){
do{
Question question = new Question ();
question.setqID(Integer.parseInt(cursor.getString(0)));
question.setqName(cursor.getString(1));
question.setqOptA(cursor.getString(2));
question.setqOptB(cursor.getString(3));
question.setqOptC(cursor.getString(4));
question.setqAns(cursor.getString(5));
//adding to list
questionList.add(question);
}while (cursor.moveToNext());
}
return questionList;
}
}
TRIVIA QUESTION ACTIVITY:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.List;
import static android.R.id.list;
public class TriviaQuestion extends AppCompatActivity {
List<Question> questionList;
int score=0;
int questionID = 0;
Question currentQ;
TextView txtQuestion;
RadioButton rda,rdb,rdc;
Button next;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trivia_question);
DBHandler db = new DBHandler(this);
questionList = db.getAllQuestions();
currentQ = questionList.get(questionID);
txtQuestion=(TextView)findViewById(R.id.textView1);
rda=(RadioButton)findViewById(R.id.radio0);
rdb=(RadioButton)findViewById(R.id.radio1);
rdc=(RadioButton)findViewById(R.id.radio2);
setQuestionView();
}
private void setQuestionView() {
txtQuestion.setText(currentQ.getqName());
rda.setText(currentQ.getqOptA());
rdb.setText(currentQ.getqOptB());
rdc.setText(currentQ.getqOptC());
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioGroup grp = (RadioGroup) findViewById(R.id.radioGroup1);
RadioButton answer = (RadioButton) findViewById(grp.getCheckedRadioButtonId());
if (currentQ.getqAns().equals(answer.getText())) {
score++;
}
currentQ = questionList.get(questionID);
setQuestionView();
}
});
}
}
TRIVIA QUESTION LAYOUT XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_trivia_question"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.rasmussenandroid.sandra.edutrivia.TriviaQuestion">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<RadioGroup
android:id="#+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.04" >
<RadioButton
android:id="#+id/radio0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" />
<RadioButton
android:id="#+id/radio2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" />
</RadioGroup>
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="next" />
</LinearLayout>
</RelativeLayout>
The error tells you what the issue is - the SQL query is not constructed properly. There should be spaces between the individual terms - for example, CREATE TABLEquestion should be CREATE TABLE question.
Try the following line for CREATE_TABLE_QUESTION :
private static final String CREATE_TABLE_QUESTION ="CREATE TABLE "
+ TABLE_QUESTION +" ( "
+ KEY_QUESTIONID +" INTEGER PRIMARY KEY, "
+ KEY_QUESTION + " TEXT , "
+ KEY_OPTIONA + " TEXT, "
+ KEY_OPTIONB + " TEXT, "
+ KEY_OPTIONC + " TEXT, "
+ KEY_ANSWER + " TEXT, "
+ KEY_LEVEL + " INTEGER, "
+ KEY_CATEGORYID + " INTEGER "+")";

Android - Import database get nullpointerexception on rawquery

I followed this tutorial to import database. Then I try to read the data using ArrayList to display them in listview. But I got nullpointer exception on my rawQuery saying it is invoking a null object reference.
DB.java
public class DB extends SQLiteOpenHelper {
//The Android's default system path of your application database.
private static String DB_PATH = "data/data/hairulhazri.malayforyou/databases/";
private static String DB_NAME = "malayforyou";
private static String TABLE_LOCATION = "Frasa";
private final Context context;
private SQLiteDatabase db;
// constructor
public DB(Context context) {
super( context , DB_NAME , null , 1);
this.context = context;
}
// Creates a empty database on the system and rewrites it with your own database.
public void create() throws IOException {
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
// By calling this method and empty database will be created into the default system path
// of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
// Check if the database exist to avoid re-copy the data
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String path = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
// database don't exist yet.
e.printStackTrace();
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
// copy your assets db to the new system DB
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = context.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
//Open the database
public boolean open() {
try {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
return true;
} catch(SQLException sqle) {
db = null;
return false;
}
}
#Override
public synchronized void close() {
if(db != null)
db.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// PUBLIC METHODS TO ACCESS DB CONTENT
// -----------------------------------------------------------------------------------------------------------------
public ArrayList<Frasa> getFrasa(String situation) {
//ArrayList of Frasa class objects
ArrayList<Frasa> arrFrasa = null;
//String query = "SELECT * FROM Frasa WHERE Situation = " + situation;
String selectQuery = "SELECT " +
Frasa.KEY_ID + "," +
Frasa.KEY_PHRASE + "," +
Frasa.KEY_TRANSLATE + "," +
Frasa.KEY_PRONOUNCE +
" FROM " + TABLE_LOCATION + " WHERE situation = " +situation;
db = SQLiteDatabase.openDatabase( DB_PATH + DB_NAME , null, SQLiteDatabase.OPEN_READWRITE);
Cursor curFrasa = db.rawQuery(selectQuery, null);
if (curFrasa != null && curFrasa.moveToFirst()) {
arrFrasa = new ArrayList<Frasa>();
while (curFrasa.isAfterLast() == false) {
//Frasa is a class with list of fields
Frasa fra = new Frasa();
fra.setId(curFrasa.getInt(curFrasa.getColumnIndex(Frasa.KEY_ID)));
fra.setPhrase(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_PHRASE)));
fra.setTranslate(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_TRANSLATE)));
fra.setPronounce(curFrasa.getString(curFrasa.getColumnIndex(Frasa.KEY_PRONOUNCE)));
arrFrasa.add(fra);
curFrasa.moveToNext();
}
}
curFrasa.close();
db.close();
return arrFrasa;
}
}
Frasa.java (Database table and columns)
public class Frasa {
// Labels Table Columns names
public static final String KEY_ID = "id";
public static final String KEY_PHRASE = "phrase";
public static final String KEY_TRANSLATE = "translate";
public static final String KEY_PRONOUNCE = "pronounce";
// property help us to keep data
public int id;
public String situation;
public String phrase;
public String translate;
public String pronounce;
public Frasa() {
}
public Frasa(int id, String situation, String phrase, String translate, String pronounce) {
this.id = id;
this.situation = situation;
this.phrase = phrase;
this.translate = translate;
this.pronounce = pronounce;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPhrase() {
return phrase;
}
public void setPhrase(String phrase) {
this.phrase = phrase;
}
public String getTranslate() {
return translate;
}
public void setTranslate(String translate) {
this.translate = translate;
}
public String getPronounce() {
return pronounce;
}
public void setPronounce(String pronounce) {
this.pronounce = pronounce;
}
}
public class GreetingAdapter extends ArrayAdapter<Frasa> {
Context context;
int layoutResourceId;
ArrayList<Frasa> data = new ArrayList<Frasa>();
public GreetingAdapter(Context context, int layoutResourceId, ArrayList<Frasa> data)
{
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
UserHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new UserHolder();
holder.textPhrase = (TextView) row.findViewById(R.id.textViewPhrase);
holder.textTranslate = (TextView) row.findViewById(R.id.textViewTranslate);
holder.btnSpeak = (Button) row.findViewById(R.id.buttonSpeak);
holder.btnRecord = (Button) row.findViewById(R.id.buttonRecord);
holder.btnPlay = (Button) row.findViewById(R.id.buttonPlay);
row.setTag(holder);
} else {
holder = (UserHolder) row.getTag();
}
Frasa frasa = data.get(position);
holder.textPhrase.setText(frasa.getPhrase());
holder.textTranslate.setText(frasa.getTranslate());
holder.btnSpeak.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Edit Button Clicked", "**********");
Toast.makeText(context, "Speak button Clicked",
Toast.LENGTH_LONG).show();
}
});
holder.btnRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Delete Button Clicked", "**********");
Toast.makeText(context, "Delete button Clicked",
Toast.LENGTH_LONG).show();
}
});
holder.btnPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.i("Play Button Clicked", "**********");
Toast.makeText(context, "Playing recorded audio",
Toast.LENGTH_LONG).show();
}
});
return row;
}
static class UserHolder {
TextView textPhrase;
TextView textTranslate;
Button btnSpeak;
Button btnRecord;
Button btnPlay;
}
}
activity_list_greetings.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/txt_header"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Greetings"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#android:color/black" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listGreetings"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/txt_header" />
list_item_greet.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textViewPhrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Phrase"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_above="#+id/buttonRecord"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/buttonSpeak"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Speak"
android:textColor="#0099CC" />
<Button
android:id="#+id/buttonRecord"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/buttonSpeak"
android:layout_marginTop="3dp"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Record"
android:textColor="#0099CC" />
<Button
android:id="#+id/buttonPlay"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_below="#+id/buttonRecord"
android:layout_marginTop="3dp"
android:background="#FFFFFF"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Play"
android:textColor="#0099CC" />
<TextView
android:id="#+id/textViewTranslate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Translate"
android:textSize="20sp"
android:textColor="#color/background_material_dark"
android:layout_below="#+id/buttonRecord"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
ListGreetings.java
public class ListGreetings extends ActionBarActivity {
TextView txtPhrase, txtTranslate;
Button speakButton;
MediaPlayer pronounce;
ListView userList;
GreetingAdapter greetAdapter;
//ArrayList<Frasa> frasaArray = new ArrayList<Frasa>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_greetings);
DB db = new DB(this);
db.open();
//get Frasa data
ArrayList<Frasa> frasaArray = db.getFrasa("Greetings");
/**
* set item into adapter
*/
greetAdapter = new GreetingAdapter(ListGreetings.this, R.layout.list_item_greet, frasaArray);
userList = (ListView) findViewById(R.id.listGreetings);
userList.setItemsCanFocus(false);
userList.setAdapter(greetAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_list_greetings, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Is it my way of calling getFrasa wrong? Or the database cannot be detected? I'm sure I already pushed the database file to both assets folder & inside the package. Sorry, if I'm not formatting the codes correctly. Thanks in advance for any help.
The problem is that you are trying to open the Database from a different location
private static String DB_PATH = "data/data/hairulhazri.malayforyou/databases/";
private static String DB_NAME = "malayforyou";
...
...
db = SQLiteDatabase.openDatabase( DB_PATH + DB_NAME , null, SQLiteDatabase.OPEN_READWRITE);
db is returning NULL because your database is stored in /assets folder not in "data/data/hairulhazri.malayforyou/databases/"

How to retrieve data on button and move to Next button? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am working on an Android quiz . I have created my database with one question and four options along-with difficulty level. I have created a layout to display the question with four buttons . Now the problem is how will i connect my database with the question and four buttons.
so as to, when I click on right button it moves to the next question and when I click on wrong button it gives an error and exits.
Code In XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:gravity="center_horizontal"
android:background="#drawable/background">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="110dp"
android:paddingTop="5dip" android:paddingBottom="5dip"
android:gravity="center_horizontal">
<ImageView
android:id="#+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:src="#drawable/logo2" />
</LinearLayout>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:paddingTop="5dip" android:paddingBottom="5dip"
android:gravity="center_horizontal">
<RadioGroup android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="vertical"
android:background="#99CCFF"
android:id="#+id/group1">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#0000CC"
android:textStyle="bold" android:id="#+id/question"/>
<Button android:onClick="false" android:id="#+id/answer1"
android:layout_width="150dip" />
<Button android:onClick="false" android:id="#+id/answer2"
android:layout_width="150dip" />
<Button android:onClick="false" android:id="#+id/answer3"
android:layout_width="150dip"/>
<Button android:onClick="false" android:id="#+id/answer4"
android:layout_width="150dip" />
</RadioGroup>
</LinearLayout>
MY DBHelper.java
public class DBHelper extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.starchazer.cyk/databases/";
private static String DB_NAME = "questionsDb";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* #param context
*/
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(!dbExist)
{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
public List<Question> getQuestionSet(int difficulty, int numQ){
List<Question> questionSet = new ArrayList<Question>();
Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE DIFFICULTY=" + difficulty +
" ORDER BY RANDOM() LIMIT " + numQ, null);
while (c.moveToNext()){
//Log.d("QUESTION", "Question Found in DB: " + c.getString(1));
Question q = new Question();
q.setQuestion(c.getString(1));
q.setAnswer(c.getString(2));
q.setOption1(c.getString(3));
q.setOption2(c.getString(4));
q.setOption3(c.getString(5));
q.setRating(difficulty);
questionSet.add(q);
}
return questionSet;
}
}
MY QuestionActivity
public class QuestionActivity extends Activity implements OnClickListener{
private Question currentQ;
private GamePlay currentGame;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
/**
* Configure current game and get question
*/
currentGame = ((XYZ_Application)getApplication()).getCurrentGame();
currentQ = currentGame.getNextQuestion();
Button c1 = (Button) findViewById(R.id.answer1 );
c1.setOnClickListener(this);
Button c2 = (Button) findViewById(R.id.answer2 );
c2.setOnClickListener(this);
Button c3 = (Button) findViewById(R.id.answer3 );
c3.setOnClickListener(this);
Button c4 = (Button) findViewById(R.id.answer4 );
c4.setOnClickListener(this);
/**
* Update the question and answer options..
*/
setQuestions();
}
/**
* 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)));
}
#Override
public void onClick(View arg0) {
/**
* validate a buttonselected has been selected
*/
if (!checkAnswer()) return;
/**
* check if end of game
*/
if (currentGame.isGameOver()){
Intent i = new Intent(this, Main.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){
return false;
}
else {
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() {
Button c1 = (Button)findViewById(R.id.answer1);
Button c2 = (Button)findViewById(R.id.answer2);
Button c3 = (Button)findViewById(R.id.answer3);
Button c4 = (Button)findViewById(R.id.answer4);
if (c1.callOnClick())
{
return c1.getText().toString();
}
if (c2.callOnClick())
{
return c2.getText().toString();
}
if (c3.callOnClick())
{
return c3.getText().toString();
}
if (c4.callOnClick())
{
return c4.getText().toString();
}
return null;
}
}
I am sorry I will not be giving code here.
Here is what I would have done
When Actvity Starts
Load Question from Db with Options
I ll prefer option as array/arraylist
Assign Text Option to each button
Add a common onclick listener like this
public void onClick(View v){
int id=v.getId();
String answer=v.getText();
if(answer.equals('ANSWER FROM DB'){
// If right then next question
// Else to MainActivity
}
/**switch(id){
case R.id.answer1:
processAnswer(1);
break;
case R.id.answer2:
processAnswer(2);
break;
// So on
}
**/
}
And processAnswer would look like
void processAnswer(int option){
// Since I have the option here
// I will check it with Database
// If its correct then next question else exit
}

Categories