Android 在第一次启动时创建SQL数据库,并在下一次启动时检索数据库数据

Android 在第一次启动时创建SQL数据库,并在下一次启动时检索数据库数据,android,sql,database,preferences,Android,Sql,Database,Preferences,关于android开发,我只是尝试在首次启动活动时创建一个SQL数据库(使用首选项)。第二次启动活动时,它应该从数据库中检索数据并输出日志消息 我第一次成功地启动了该活动(我假设数据库是在这里创建的),但第二次出现IllegalStateException错误:从第0行到第1列获取字段槽失败。我不太确定我哪里出了问题。有人能查一下吗?谢谢 主类 public class MainMenu extends Activity implements OnClickListener{ private M

关于android开发,我只是尝试在首次启动活动时创建一个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.

}

我相信您的问题在您的日志行中。将字符串更改为文字:

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

错误很简单。您在DbAdapter类中将KEY_BODY定义为静态字符串常量值,但在访问代码中使用了字符串文字“KEY_BODY”

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

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

您不必显式检查数据库是否已创建。如果您创建了一个实现onCreate(SQLiteDatabase)、onUpgrade(SQLiteDatabase、int、int)的SQLiteOpenHelper子类,它将“知道”不创建数据库,如果它已经存在的话

否则,您的错误将在以下行中引起:

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

因为您使用的是字符串“KEY\u BODY”作为列索引,而不是静态字符串变量KEY\u BODY的值。

不过,我想添加一些注释。我会抽出所有“第一时间”的东西,打开数据库,数一数行数。如果为0,则执行init插入。而且,“firsttimer”也让人困惑,因为你第一次跑步时,它是错误的,尽管逻辑上会说它应该是正确的,对吗?哦,亲爱的,为什么我没看到!!谢谢你,现在很好用。关于firsttimer,是的,它在第一次运行时为false,但在创建数据库后变为true。因为现在它仍然是真的,所以它不会再次创建数据库。我的意思是变量的名称没有意义firsttimer’在您第一次运行时为false,但其名称将暗示它为true。代码将按原样工作,但我会更改名称,这样您就不会在路上混淆自己。