androidsqlitenullpointerexceptioncalllog

Storing Calllog details into a SQLite DB


I am having some trouble with my application.

What I am trying to do is get the call records from the call Log, pass it into my DB for storage and then retrieve values as and when needed to be displayed.

The DB gets created but looks like the values are refusing to be inserted. below is my code and the logcat.

Help is very much appreciated.

MY MAIN ACTIVITY

package com.example.mobilebillforecaster;

import com.example.mbf.R;

import android.app.TabActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Handler;
import android.provider.CallLog;
import android.widget.TabHost;
import android.widget.TextView;

@SuppressWarnings({ "deprecation", "deprecation" })
public class EtiMainScreen extends TabActivity {

SQLiteDatabase calllog;

Handler hand = new Handler();
Cursor cursor;
ContentValues cv;

TextView tvnatmins, tvintmins, tvnatsms;

@SuppressWarnings("deprecation")
protected void onCreate(Bundle Bundle) {
    super.onCreate(Bundle);
    setContentView(R.layout.eti_main_screen);
    TabHost.TabSpec spec = getTabHost().newTabSpec("tag1");

    spec.setContent(R.id.mainmenu);
    spec.setIndicator("Main Menu");
    getTabHost().addTab(spec);

    spec = getTabHost().newTabSpec("tag2");
    spec.setContent(R.id.billhist);
    spec.setIndicator("Billing History");
    getTabHost().addTab(spec);

    getTabHost().setCurrentTab(0);

    tvnatmins = (TextView) findViewById(R.id.tvnatmins);
    tvintmins = (TextView) findViewById(R.id.tvintmins);
    tvnatsms = (TextView) findViewById(R.id.tvnatsms);

    getCallDetails();

}

private void getCallDetails() {

    CallRecords recdb = new CallRecords();

    StringBuffer sb = new StringBuffer();
    Cursor managedCursor = getContentResolver().query(
            CallLog.Calls.CONTENT_URI, null, null, null, null);
    int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
    int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
    int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);

    while (managedCursor.moveToNext()) {

        String callDuration = managedCursor.getString(duration);

        recdb.open();

        cv.put("CALL_NUMBER", number);
        cv.put("CALL_TYPE", type);
        cv.put("CALL_DURATION", duration);
        recdb.insertValues("Records", cv);
        recdb.close();

        sb.append("" + callDuration);

    }
    managedCursor.close();
    tvnatmins.setText(sb);
}

// tvnatmins.setText(number);
// tvintmins.setText(type);
// tvnatsms.setText(duration);

}

MY DB

package com.example.mobilebillforecaster;



import android.content.Context;

import android.content.ContentValues;
import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CallRecords {

private static final int DATABASE_VERSION = 1;
private DatabaseHelper DBhelper;
public SQLiteDatabase callDB;
static final String DATABASE_NAME = "DBLogs";
static final String TABLE_NAME = " Records";

public static final String CALL_ROWID = "_id";
public static final String CALL_NUMBER = "cnumber";
public static final String CALL_DURATION = "cduration";
public static final String CALL_TYPE = "ctype";

Context context;

private static final String Records = "CREATE TABLE " + TABLE_NAME + "("
        + CALL_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + CALL_NUMBER
        + " INTEGER, " + CALL_DURATION + " INTEGER, " + CALL_TYPE
        + " INTEGER" + ");";

private static class DatabaseHelper extends SQLiteOpenHelper {

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL(Records);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS" + Records);

    }

}

public CallRecords open() {

    DBhelper = new DatabaseHelper(context);
    callDB = DBhelper.getWritableDatabase();

    return this;

}

public void close() {
    DBhelper.close();
}

public long insertValues(String rectable, ContentValues conValues) {
    return callDB.insert(rectable, null, conValues);

}

public Cursor getAllLogs() {

    String sql = "SELECT CALL_ROWID ,CALL_TYPE , CALL_DURATION, CALL_NUMBER 
FROM Records ";
    Cursor cursor = callDB.rawQuery(sql, null);
    return cursor;

}
}

and finally my LOGCAT

04-21 20:42:57.294: E/AndroidRuntime(9388): FATAL EXCEPTION: main
04-21 20:42:57.294: E/AndroidRuntime(9388): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mbf/com.example.mobilebillforecaster.EtiMainScreen}: java.lang.NullPointerException
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.os.Looper.loop(Looper.java:137)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread.main(ActivityThread.java:5039)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at java.lang.reflect.Method.invokeNative(Native Method)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at java.lang.reflect.Method.invoke(Method.java:511)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at dalvik.system.NativeStart.main(Native Method)
04-21 20:42:57.294: E/AndroidRuntime(9388): Caused by: java.lang.NullPointerException
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at com.example.mobilebillforecaster.CallRecords.open(CallRecords.java:59)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at com.example.mobilebillforecaster.EtiMainScreen.getCallDetails(EtiMainScreen.java:66)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at com.example.mobilebillforecaster.EtiMainScreen.onCreate(EtiMainScreen.java:47)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.Activity.performCreate(Activity.java:5104)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-21 20:42:57.294: E/AndroidRuntime(9388):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
04-21 20:42:57.294: E/AndroidRuntime(9388):     ... 11 more

Thank you!


Solution

  • In your declaration of cv change to ContentValues cv = new ContentValues();

    You need a constructor in CallRecords

    public CallRecords(Context context)
    {
        this.context = context;
    }
    

    Change CallRecords recdb = new CallRecords();
    To CallRecords recdb = new CallRecords(this);