1

Hey I'm trying to insert data in the SQLite database, but everytime I try to insert the logcat shows the error. THe error ir shown on a service that gets the calllog data and insert in the DB.

Error:

02-15 17:07:51.658: ERROR/AndroidRuntime(25392): java.lang.IllegalStateException: database not open

And the error is in this line of the Service class:

db.insert(DataHandlerDB.TABLE_NAME_2, null, values);

Here is the service:

public class TheService extends Service {

    private static final String TAG = "TheService";
    private static final String LOG_TAG = "TheService";
    private Handler handler = new Handler();
    private SQLiteDatabase db;

    class TheContentObserver extends ContentObserver {

        public TheContentObserver(Handler h) {

            super(h);
            OpenHelper helper = new OpenHelper(getApplicationContext());
            SQLiteDatabase db = helper.getWritableDatabase();

        }

        @Override
        public boolean deliverSelfNotifications() {

            return true;

        }

        @Override
        public void onChange(boolean selfChange) {

            super.onChange(selfChange);
            searchInsert();
        }
    }

    @Override
    public IBinder onBind(Intent arg0) {

        return null;

    }

    @Override
    public void onCreate() {

        db = DataHandlerDB.createDB(this);
        registerContentObservers();

    }

    @Override
    public void onDestroy(){

        db.close();

    }

    @Override
    public void onStart(Intent intent, int startid) {

    }

    private void searchInsert() {

        Cursor cursor = getContentResolver().query(
                android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
                android.provider.CallLog.Calls.DATE + " DESC ");

        int numberColumnId = cursor
                .getColumnIndex(android.provider.CallLog.Calls.NUMBER);
        int durationId = cursor
                .getColumnIndex(android.provider.CallLog.Calls.DURATION);
        int contactNameId = cursor
                .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
        int numTypeId = cursor
                .getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
        int callTypeId = cursor
                .getColumnIndex(android.provider.CallLog.Calls.TYPE);

        Date dt = new Date();
        int hours = dt.getHours();
        int minutes = dt.getMinutes();
        int seconds = dt.getSeconds();
        String currTime = hours + ":" + minutes + ":" + seconds;

        SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy");
        Date date = new Date();

        cursor.moveToFirst();

        String contactNumber = cursor.getString(numberColumnId);
        String contactName = (null == cursor.getString(contactNameId) ? ""
                : cursor.getString(contactNameId));
        String duration = cursor.getString(durationId);
        String numType = cursor.getString(numTypeId);
        String callType = cursor.getString(callTypeId);

        ContentValues values = new ContentValues();

        values.put("contact_id", 1);
        values.put("contact_name", contactName);
        values.put("number_type", numType);
        values.put("contact_number", contactNumber);
        values.put("duration", duration);
        values.put("date", dateFormat.format(date));
        values.put("current_time", currTime);
        values.put("cont", 1);
        values.put("type", callType);

        if (!db.isOpen()) {
            getApplicationContext().openOrCreateDatabase(
                    "/data/data/com.my_app/databases/mydb.db",
                    SQLiteDatabase.OPEN_READWRITE, null);
        }
        db.insert(DataHandlerDB.TABLE_NAME_2, null, values);
        cursor.close();


    }

    public void registerContentObservers() {

        this.getApplicationContext()
                .getContentResolver()
                .registerContentObserver(
                        android.provider.CallLog.Calls.CONTENT_URI, true,
                        new TheContentObserver(handler));

    }

}

And here is the DataHandlerDB Class:

public class DataHandlerDB {

    private static final String DATABASE_NAME = "mydb.db";
    private static final int DATABASE_VERSION = 1;
    protected static final String TABLE_NAME = "table1";
    protected static final String TABLE_NAME_2 = "table2";
    protected String TAG = "DataHandlerDB";

//create the DB     
    public static SQLiteDatabase createDB(Context ctx) {
        OpenHelper helper = new OpenHelper(ctx);
        SQLiteDatabase db = helper.getWritableDatabase();
        helper.onOpen(db);
        db.close();
        return db;
    }
public static class OpenHelper extends SQLiteOpenHelper {

        private final Context mContext;

        OpenHelper(Context context) {

            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.mContext = context;

        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            String[] sql = mContext.getString(R.string.ApplicationDatabase_OnCreate).split("\n");

            db.beginTransaction();

            try{
                execMultipleSQL(db, sql);
                db.setTransactionSuccessful();
            } catch (SQLException e) {

                Log.e("Error creating tables and debug data", e.toString());
                throw e;

            } finally {
                db.endTransaction();

            }
        }

        private void execMultipleSQL(SQLiteDatabase db, String[] sql) {

            for(String s : sql){

                if(s.trim().length() > 0){

                    db.execSQL(s);
                }
            }

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            /*Log.w("Application Database",
                    "Upgrading database, this will drop tables and recreate.");
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);*/
        }

        @Override 
        public void onOpen(SQLiteDatabase db){

            super.onOpen(db);
        }

    }
}
8
  • @psyhclo First you should change what Dan Breslau mentions. There are also some other things I would change. I have to take a look tomorrow. Did you try this already? Commented Feb 15, 2011 at 21:59
  • @Beasly I'm gonna try it now. Commented Feb 15, 2011 at 22:14
  • I assume it works now. But the OpenHelper should be called just in your DataHandlerDB Commented Feb 16, 2011 at 9:13
  • @Beasly How to call only on the DataHandlerDB if I need to open the DB on the activity, and for that the only solution I found was instatiate the helper and db objects so I can open the database on the activity. Do you have another solution for this problem?? Thanks man!! =) Commented Feb 16, 2011 at 13:36
  • Your mehtods in DataHandlerDB are static so just implement e.g. a insert method with the needed parameters. Then call in your activity DataHanderDB.insert(...); Commented Feb 16, 2011 at 14:09

1 Answer 1

4

Don't you want this code

 if (!db.isOpen()) {
        getApplicationContext().openOrCreateDatabase(
                "/data/data/com.my_app/databases/mydb.db",
                SQLiteDatabase.OPEN_READWRITE, null);
 }

to be:

 if (!db.isOpen()) {
    db = getApplicationContext().openOrCreateDatabase(
                "/data/data/com.my_app/databases/mydb.db",
                SQLiteDatabase.OPEN_READWRITE, null);
 }

?

Also, in the function

    public TheContentObserver(Handler h) {
        super(h);
        OpenHelper helper = new OpenHelper(getApplicationContext());
        SQLiteDatabase db = helper.getWritableDatabase();
    }

helper and db are local variables, not class members. This means that the database that you open here is not used for anything, anywhere.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.