2016-04-28 83 views
0

我想添加一个TIMESTAMP列到我的SQLite数据库。该列将用于使用“System.currentTimeMillis();”来捕获时间戳记数据。应用程序崩溃,错误来自下面的** **行所示的光标代码。错误信息为“无法启动活动ComponentInfo {... ListActivity}:java.lang.IllegalStateException:无法从CursorWindow读取第0行,第6列。确保游标在从中访问数据前正确初始化。Android:我如何解决时间戳添加到我的SQLite数据库?

最初,我在模型文件中将变量设置为字符串。然后我尝试了很长时间,但都没有成功。我在这里错过了什么?

的UserData文件:

... 
public long getTimestamp() { 
    return timestamp; 
} 

public void setTimestamp(long timestamp) { 
    this.timestamp = timestamp; 

DatabaseHelper.java文件:

... 
private static final String SQL_CREATE_ENTRIES = 
     "CREATE TABLE IF NOT EXISTS " + DBContract.DBEntry.TABLE_NAME + 
      "(" + DBContract.DBEntry.COLUMN_NAME_ID + 
        " INTEGER PRIMARY KEY AUTOINCREMENT," 
       + DBContract.DBEntry.COLUMN_NAME_TODO + 
        " TEXT," 
       + DBContract.DBEntry.COLUMN_NAME_NOTE1 + 
        " TEXT," 
       + DBContract.DBEntry.COLUMN_NAME_NOTE2 + 
        " TEXT," 
       + DBContract.DBEntry.COLUMN_NAME_DUEDATE + 
        " TEXT," 
       + DBContract.DBEntry.COLUMN_NAME_DUETIME + 
       " TEXT," 
       + DBContract.DBEntry.COLUMN_NAME_TIMESTAMP + 
        " TEXT" + ")"; 
... 

public void insertIntoDB(String todo, String note1, String note2, String duedate, String duetime, long timestamp) { 

    SQLiteDatabase db = this.getWritableDatabase(); 

    ContentValues values = new ContentValues(); 
    values.put(DBContract.DBEntry.COLUMN_NAME_TODO, todo); 
    values.put(DBContract.DBEntry.COLUMN_NAME_NOTE1, note1); 
    values.put(DBContract.DBEntry.COLUMN_NAME_NOTE2, note2); 
    values.put(DBContract.DBEntry.COLUMN_NAME_DUEDATE, duedate); 
    values.put(DBContract.DBEntry.COLUMN_NAME_DUETIME, duetime);   
    values.put(DBContract.DBEntry.COLUMN_NAME_TIMESTAMP, timestamp); 

    db.insert(DBContract.DBEntry.TABLE_NAME, null, values); 
    db.close(); 
} 
... 

Cursor cursor = db.rawQuery(query,null); 

     try { 
      if (cursor.moveToFirst()) { 
       do { 
        UserData userData = new UserData(); 
        userData.setTodo(cursor.getString(1)); 
        userData.setNote1(cursor.getString(2)); 
        userData.setNote2(cursor.getString(3)); 
        userData.setDuedate(cursor.getString(4)); 
        userData.setDuetime(cursor.getString(5)); 
        **userData.setTimestamp(cursor.getLong(6));** 

        modelList.add(0, userData); 
        } while (cursor.moveToNext()); 
... 

ListAdapter.java文件:

... 
public void onBindViewHolder(final ListViewHolder holder, final int position) { 
    ... 
    holder.cardBlankText5.setText((int) dbList.get(position).getTimestamp()); 

Activity.java文件:

... 
public void onClickSave(View v) { 
    ... 
    long timestamp=System.currentTimeMillis(); 
    helper = new DatabaseHelper(Activity.this); 
    helper.insertIntoDB(todo,note1,note2,duedate,duetime,timestamp); 
    startActivity(new Intent(Activity.this,ListActivity.class)); 
} 
+0

,你看到了什么? – pskink

+0

显示查询。 –

+0

@CL你的意思是调用dumpCursor并显示Logcat结果? – AJW

回答

-1

DBContract.DBEntry.COLUMN_NAME_TIMESTAMP作为DATETIME类型应该有效。我通常有实用方法,它采用光标,列名和返回日期对象:

public static Date getDateColumn(Cursor c, String column) { 
    Date d = null; 
    Long time = c.getLong(c.getColumnIndexOrThrow(column)); 
    if (time != null && time != 0) { 
     d = new Date(); 
     d.setTime(time); 
    } 
    return d; 
} 

检查的第二件事是,是否该字段被要求在您的查询。分享query的价值可能会带来一些亮点,但通常当您要求的列不在投影中时,您会得到类似的情况。

例如从mytable中选择columnA,columnB;然后尝试从列C中获取某些不在结果中的内容。

+0

正确,所以我试图对数据库执行查询并在光标中设置时间戳数据,以便我可以在RecyclerView列表中使用光标。不知道如何使用您的实用程序方法与我的userData对象的游标,如上所示。 – AJW

+0

只有第3行与您相关,因为您希望将其作为长时间存储在POJO中,如果要将其作为Date对象存储,则该方法非常有用。无论如何,在表中存储为'DATETIME'应该可以解决您的问题。确保在删除应用程序并在更改表格定义后重新安装它。 – rossco

+0

所以你建议用“DATETIME”替换TIMESTAMP的“TEXT”? – AJW

-1

不要试图从声明为TEXT的列中获取Long。将其声明为INTEGER。 或使用getString()并将值转换为Long。在`rawQuery`调用`DatabaseUtils#dumpCursor`之后的

+0

啊,是的。我会尝试用INT替换。 – AJW

+0

没有运气,抛出同样的错误。 – AJW

+0

您确定数据库是在设备/模拟器上重新创建的吗?或者你使用db与旧值? –