【发布时间】:2011-02-15 20:05:19
【问题描述】:
嘿,我正在尝试在 SQLite 数据库中插入数据,但每次我尝试插入 logcat 时都会显示错误。获取呼叫日志数据并插入数据库的服务上显示的错误。
错误:
02-15 17:07:51.658: 错误/AndroidRuntime(25392): java.lang.IllegalStateException: 数据库未打开
而错误在Service类的这一行:
db.insert(DataHandlerDB.TABLE_NAME_2, null, values);
这里是服务:
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));
}
}
这里是 DataHandlerDB 类:
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);
}
}
}
【问题讨论】:
-
@psyhclo 首先,您应该更改 Dan Breslau 提到的内容。还有一些其他的事情我会改变。明天我得去看看。你试过了吗?
-
@Beasly 我现在就试试。
-
我认为它现在可以工作了。但是
OpenHelper应该在你的DataHandlerDB中调用 -
@Beasly 如果我需要在活动上打开数据库,如何仅在 DataHandlerDB 上调用,为此我找到的唯一解决方案是设置帮助程序和数据库对象,以便我可以打开数据库活动。你有这个问题的另一种解决方案吗?谢啦!! =)
-
您在 DataHandlerDB 中的方法是静态的,因此只需实现例如具有所需参数的插入方法。然后调用你的活动
DataHanderDB.insert(...);