maidi maidi - 12 days ago 8
Android Question

Runtime Exception: NullPointerException with SQLite Database

I have an Andorid App with Google Maps and Markers. If you click at one marker you get to an "Home Screen" of the Location where you can start a quiz with a Button. After going through 5 Multiple Choice Questions the Score is shown (1 - 5 Points). To this Point everthing was working.
Now I want to save the Score in a SQLite Database and change an image at the "Home Screen" if the Score is 5.
Now everytime I test and click on a Marker to open the "Home Screen"(where the image should be changed if Score is = 5) of a specific location the App crashes.
Until now there is no data in the table because I never ran through a quiz to save a score. I would be very thankful if someone finds a mistake!

Here is my Code:

Database Helper:

public class DbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 7;
private static final String DATABASE_NAME = "CE";

public static final String SCORE_TABLE = "score";
public static final String COLUMN_ID = "ID";
public static final String COLUMN_SCORE = "SCORE";
public static final String COLUMN_MARKERID = "MARKERID";

private SQLiteDatabase dbase;

public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);

}
@Override
public void onCreate(SQLiteDatabase db) {
//Hier alle Tables erstellen

String create_query = "CREATE TABLE IF NOT EXITS " + SCORE_TABLE + " ( "
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_SCORE + " INTEGER, "
+ COLUMN_MARKERID + " TEXT) ";
db.execSQL(create_query);
}

public void addScore (DbHelper dbh, Integer score, String markerID) {
dbase = dbh.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_SCORE, score);
cv.put(COLUMN_MARKERID, markerID);
dbase.insert(SCORE_TABLE, null, cv);
}

public Cursor getScore(DbHelper dbh) {
dbase = dbh.getReadableDatabase();
String columns[] = {COLUMN_SCORE, COLUMN_MARKERID};
Cursor cursor = dbase.query(SCORE_TABLE, columns, null, null, null, null, null);
return cursor;
}


Write the Score into the Database after completing the Quiz in ResultActivity:

public class ResultActivity extends Activity {

String markerID;
int score;
TextView t=(TextView)findViewById(R.id.textResult);
Button saveButton = (Button) findViewById(R.id.saveButton);
Context context = this;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result_layout);

Bundle b = getIntent().getExtras();
score = b.getInt("score");
markerID = b.getString("markerID");
}

saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DbHelper dbh = new DbHelper(context);
dbh.addScore(dbh,score,markerID);
}
});
}


Look at the "Home Screen" what Score is saved on this marker:

public class Discover extends ActionBarActivity {

TextView InfoHeadline;
ImageView ImageDone;
Button QuizButton;

String markerID;

Context context;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.discover_layout);

InfoHeadline = (TextView)findViewById(R.id.InfoUeberschrift);
ImageDone =(ImageView)findViewById(R.id.imageDone);
QuizButton = (Button)findViewById(R.id.QuizButton);

//get markerID from previous google maps activity
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
markerID= null;
} else {
markerID= extras.getString("MarkerID");
}
} else {
markerID = (String) savedInstanceState.getSerializable("MarkerID");
}

InfoHeadline.setText(markerID);

DbHelper dbh = new DbHelper(context);
Cursor cursor = dbh.getScore(dbh);
cursor.moveToFirst();
do {
if (Integer.parseInt(cursor.getString(0))== 5 && InfoHeadline.toString().equals(cursor.getString(1))){
ImageDone.setImageResource(R.drawable.markerdone);
}
}while(cursor.moveToNext());
}

public void StartQuiz (View v) {
Intent intent = new Intent(Discover.this,QuizActivity.class);
intent.putExtra("MarkerID", markerID);
startActivity(intent);
}
}


Here is the crash report:

java.lang.RuntimeException: Unable to start activity ComponentInfo{de.marmor.discover/de.marmor.discover.Discover}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2345)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2407)
at android.app.ActivityThread.access$800(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1324)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5321)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at de.marmor.discover.DbHelper.getScore(DbHelper.java:71)
at de.marmor.discover.Discover.onCreate(Discover.java:46)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)`


...

Answer

The context in your Discover is not initialized and you're passing a null for a context to your DbHelper.

Since Discover is an Activity and an Activity is a Context, you can just use this in place of context.