2016-04-28 9 views
0

Ich versuche, eine TIMESTAMP-Spalte zu meiner SQLite-Datenbank hinzuzufügen. Die Spalte soll verwendet werden, um Zeitstempeldaten mit "System.currentTimeMillis();" zu erfassen. App stürzt ab und der Fehler kommt vom Cursor-Code unten in der Zeile mit ** **. Der Fehler lautet "Aktivität kann nicht gestartet werden ComponentInfo {... ListActivity}: java.lang.IllegalStateException: Zeile 0, Spalte 6 von CursorWindow konnte nicht gelesen werden. Stellen Sie sicher, dass der Cursor korrekt initialisiert ist, bevor Sie auf Daten zugreifen."Android: Wie behebe ich Timestamp-Zusatz zu meiner SQLite-Datenbank?

Zunächst habe ich die Variable als String in der Modelldatei eingerichtet. Dann habe ich es lange versucht und keiner hat funktioniert. Was fehlt mir hier?

Userdata-Datei:

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

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

DatabaseHelper.java Datei:

... 
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 Datei:

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

Activity.java Datei:

... 
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

nach 'rawQuery' Aufruf' DatabaseUtils # dumpCursor', was siehst du? – pskink

+0

Zeigen Sie die Abfrage an. –

+0

@CL Meinst du call dumpCursor und zeige das Logcat-Ergebnis? – AJW

Antwort

-1

Nach DBContract.DBEntry.COLUMN_NAME_TIMESTAMP als DATETIME Typ sollte funktionieren. Ich habe in der Regel Hilfsmethode, die den Cursor und Spaltennamen nimmt und gibt ein Objekt Datum:

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

Die zweite Sache zu prüfen, ob oder nicht das Feld in Ihrer Abfrage gefragt wird. Den Wert von query zu teilen, könnte etwas Licht freilassen, aber normalerweise erhalten Sie solche Dinge, wenn die Spalte, nach der Sie fragen, nicht in der Projektion ist.

z.B. wähle columnA, columnB von mytable; und dann versuchst du etwas von columnC zu bekommen, was nicht in den Ergebnissen ist.

+0

Richtig, also versuche ich, die Abfrage in der Datenbank durchzuführen und die Zeitstempeldaten im Cursor zu setzen, damit ich den Cursor in einer RecyclerView-Liste verwenden kann. Nicht sicher, wie ich Ihre Hilfsmethode mit meinem userData-Objekt für den Cursor verwenden würde, wie oben gezeigt. – AJW

+0

Nur Zeile 3 ist relevant für Sie, wie Sie es als eine lange in Ihrem POJO speichern möchten, wenn Sie es als ein Date-Objekt speichern möchten, dann ist die Methode nützlich. In jedem Fall sollte das Speichern als 'DATETIME' in der Tabelle Ihr Problem lösen. Stellen Sie sicher, dass Sie Ihre App entfernen und sie erneut installieren, nachdem Sie die Tabellendefinition geändert haben. – rossco

+0

Sie empfehlen also, den "TEXT" für TIMESTAMP durch "DATETIME" zu ersetzen? – AJW

-1

Versuchen Sie nicht Long aus Spalte als TEXT deklariert zu bekommen. Deklarieren Sie es als INTEGER. Oder verwenden Sie getString() und konvertieren Sie den Wert in Long.

+0

Ah, ja. Ich werde versuchen, mit INT zu ersetzen. – AJW

+0

Kein Glück, der gleiche Fehler wird geworfen. – AJW

+0

Sind Sie sicher, dass die Datenbank auf dem Gerät/Emulator neu erstellt wurde? Oder verwenden Sie db mit alten Werten? –

Verwandte Themen