Java 错误:数据库未打开

Java 错误:数据库未打开,java,android,sqlite,Java,Android,Sqlite,嘿,我试图在SQLite数据库中插入数据,但每次我尝试插入logcat时都会显示错误。获取调用日志数据并插入数据库的服务上显示的错误ir 错误: 02-15 17:07:51.658:错误/AndroidRuntime(25392):java.lang.IllegalStateException:数据库未打开 错误在服务类的这一行: 插入(DataHandlerDB.TABLE_NAME_2,null,值) 这是服务: public class TheService extends Servic

嘿,我试图在SQLite数据库中插入数据,但每次我尝试插入logcat时都会显示错误。获取调用日志数据并插入数据库的服务上显示的错误ir

错误:

02-15 17:07:51.658:错误/AndroidRuntime(25392):java.lang.IllegalStateException:数据库未打开

错误在服务类的这一行:

插入(DataHandlerDB.TABLE_NAME_2,null,值)

这是服务:

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

    }

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

    }
}
下面是DataHandlerDB类:

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

    }

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

    }
}

你不想要这个密码吗

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

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

另外,在函数中

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

helper
db
是局部变量,而不是类成员。这意味着您在此处打开的数据库不用于任何地方的任何内容。

您不需要此代码吗

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

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

另外,在函数中

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

helper
db
是局部变量,而不是类成员。这意味着您在此处打开的数据库不会用于任何地方。

@psyhclo首先您应该更改丹·布雷斯劳提到的内容。还有一些事情我会改变。我明天得去看看。你已经试过了吗?@Beasly我现在要试一下。我想现在可以了。但是,
OpenHelper
应该只在您的
DataHandlerDB
@中调用,因为如果我需要在活动上打开数据库,那么如何仅在DataHandlerDB上调用,因此我找到的唯一解决方案是安装helper和DB对象,以便我可以在活动上打开数据库。对于这个问题,您有其他解决方案吗??谢谢你,伙计!!=)DataHandlerDB中的方法是静态的,所以只需使用所需的参数实现一个插入方法。然后调用活动
DataHanderDB.insert(…)
@psyhclo首先你应该改变丹·布雷斯劳提到的内容。还有一些事情我会改变。我明天得去看看。你已经试过了吗?@Beasly我现在要试一下。我想现在可以了。但是,
OpenHelper
应该只在您的
DataHandlerDB
@中调用,因为如果我需要在活动上打开数据库,那么如何仅在DataHandlerDB上调用,因此我找到的唯一解决方案是安装helper和DB对象,以便我可以在活动上打开数据库。对于这个问题,您有其他解决方案吗??谢谢你,伙计!!=)DataHandlerDB中的方法是静态的,所以只需使用所需的参数实现一个插入方法。然后调用活动
DataHanderDB.insert(…)