2011-11-13 50 views
2

有關android開發,我只是試圖創建一個SQL數據庫時首次啓動活動(使用首選項)。活動第二次啓動時,它應該從數據庫檢索數據並輸出日誌消息。首次啓動時創建SQL數據庫,並在下次啓動時檢索數據庫數據

我第一次設法啓動活動(即時假設數據庫是在這裏創建的),但第二次我得到一個IllegalStateException錯誤:從第0行到第1列的字段插槽失敗。不確定我在哪裏出錯了。有人可以檢查嗎?由於

主要類

public class MainMenu extends Activity implements OnClickListener{ 
private ModulesDbAdapter mpDbHelper; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //create database here 
    SharedPreferences initialPref = getSharedPreferences("INITIAL", 0); 
    boolean firsttimer = initialPref.getBoolean("INITIAL", false); 

    if (!firsttimer){ 
     //create database here 
     mpDbHelper = new ModulesDbAdapter(this); 
     mpDbHelper.open(); 

     long id1 = mpDbHelper.createReminder("Hello1", "Test 1", "Date1"); 
     long id2 = mpDbHelper.createReminder("Hello2", "Test 2", "Date2"); 
     long id3 = mpDbHelper.createReminder("Hello3", "Test 3", "Date3"); 

     /*Cursor c = mpDbHelper.fetchModules((String)"CS118"); 
     Log.d("TESTING",c.getString(c.getColumnIndex("KEY_MOD_NAME")));*/ 

     //get boolean preference to true 
     SharedPreferences.Editor editorPref = initialPref.edit(); 
     editorPref.putBoolean("INITIAL", true); 
     editorPref.commit(); 
    }else { 
     fetchData(); 
    } 
} 

private void fetchData(){ 
    mpDbHelper = new ModulesDbAdapter(this); 
    mpDbHelper.open(); 
    long input = 2; 

    Cursor c = mpDbHelper.fetchReminder(input); 
    startManagingCursor(c); 
    Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 
} 

/*@Override 
protected void onPause() { 
    super.onPause(); 
    mpDbHelper.close(); 
} 

@Override 
protected void onStop() { 
    super.onPause(); 
    mpDbHelper.close(); 
}*/ 

} 
} 

適配器類

public class ModulesDbAdapter { 
private static final String DATABASE_NAME = "data"; 
private static final String DATABASE_TABLE = "reminders"; 
private static final int DATABASE_VERSION = 1; 

public static final String KEY_TITLE = "title"; 
public static final String KEY_BODY = "body"; 
public static final String KEY_DATE_TIME = "reminder_date_time"; 
public static final String KEY_ROWID = "_id"; 

private DatabaseHelper mDbHelper; 
private SQLiteDatabase mDb; 

//defines the create script for the database 
private static final String DATABASE_CREATE = 
     "create table " + DATABASE_TABLE + " (" 
     + KEY_ROWID + " integer primary key autoincrement, " 
     + KEY_TITLE + " text not null, " 
     + KEY_BODY + " text not null, " 
     + KEY_DATE_TIME + " text not null);"; 

//Context object that will be associated with the SQLite database object 
private final Context mCtx; 

//The Context object is set via the constructor of the class 
public ModulesDbAdapter(Context ctx) { 
    this.mCtx = ctx; 
} 

//helps with the creation and version management of the SQLite database. 
private static class DatabaseHelper extends SQLiteOpenHelper { 

    //call made to the base SQLiteOpenHelper constructor. This call creates, opens, and/or manages a database 
    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DATABASE_CREATE); 
    } 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion) { 
     // Not used, but you could upgrade the database with ALTER 
     // Scripts 
    } 
} 

//now create the database by calling the getReadableDatabase() 
public ModulesDbAdapter open() throws android.database.SQLException { 
    mDbHelper = new DatabaseHelper(mCtx); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
} 

//close the database 
public void close() { 
    mDbHelper.close(); 
} 

public long createReminder(String title, String body, String 
    reminderDateTime) { 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put(KEY_TITLE, title); 
    initialValues.put(KEY_BODY, body); 
    initialValues.put(KEY_DATE_TIME, reminderDateTime); 

    //insert row into database 
    return mDb.insert(DATABASE_TABLE, null, initialValues); 
} 



public boolean deleteReminder(long rowId) { 
    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; 
} 

//utilizes the query() method on the SQLite database to find all the reminders in the system 
public Cursor fetchAllReminders() { 
    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE, 
    KEY_BODY, KEY_DATE_TIME}, null, null, null, null, null); 
} 

public Cursor fetchReminder(long rowId) throws SQLException { 
    Cursor mCursor = 
    mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, 
    KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, KEY_ROWID + "=" + 
    rowId, null, null, null, null, null); 



    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 
} 

public boolean updateReminder(long rowId, String title, String body, String reminderDateTime) { 
    ContentValues args = new ContentValues(); 
    args.put(KEY_TITLE, title); 
    args.put(KEY_BODY, body); 
    args.put(KEY_DATE_TIME, reminderDateTime); 
    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; 
} 
     // The SQLiteOpenHelper class was omitted for brevity 
     // That code goes here. 

}

回答

1

錯誤很簡單。您已經在DbAdapter類中將KEY_BODY定義爲靜態字符串常量值,但在訪問代碼中使用了字符串文字「KEY_BODY」。

Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 

應該

Log.d("TESTING",c.getString(c.getColumnIndex(ModulesDbAdapter.KEY_BODY))); 
+0

雖然我想補充一些意見。我會推出所有'最初'的東西,打開數據庫並統計行數。如果爲0,那麼你的init插入。另外,'初生'是混亂的,因爲你第一次跑,它的錯誤,雖然邏輯會說它應該是真的,對嗎? –

+0

ohh親愛的,爲什麼我沒看見那!謝謝你,現在工作正常。關於firsttimer,是的,它在第一次運行時是錯誤的,但在創建數據庫後變爲true。由於它現在仍然如此,它不會再次創建數據庫。 –

+0

我的意思是變量名稱沒有意義。你第一次跑步的時候,'初生'是假的,但這個名字意味着它是真的。該代碼將按原樣工作,但我會更改名稱,以免您將自己困在路上。 –

0

我相信你的問題是你的日誌行。將字符串更改爲文字:

Log.d("TESTING",c.getString(c.getColumnIndex(KEY_BODY))); 
1

您沒有明確檢查,如果你的數據庫已經創建。如果創建實現onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase,int,int)的SQLiteOpenHelper的子類,它將「知道」不創建數據庫(如果它已經存在)。

否則,你的錯誤是在該行造成的:

Log.d("TESTING",c.getString(c.getColumnIndex("KEY_BODY"))); 

,因爲你使用的列索引字符串「KEY_BODY」,而不是你的靜態字符串變量KEY_BODY的價值。

相關問題