I'm creating an app which uses SQLiteDatabase to store items of a ListView
. But, I get an error while populating the data in the ListView
from the Database, and the app crashes.
Here's my Database -
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class NotesDatabase extends SQLiteOpenHelper {
private static final String NOTE_NAME = "name";
private static final String NOTE_ID = "id";
private static final String NOTE_SUBJECT = "subject";
private static final String DATABASE_NAME = "notesDatabase";
private static final String TABLE_NOTES = "notes";
private static final int DATABASE_VERSION = 1;
private static final String CREATE_NOTES_TABLE = "CREATE TABLE " + TABLE_NOTES + "("
+ NOTE_ID + " INTEGER PRIMARY KEY," + NOTE_NAME + " TEXT,"
+ NOTE_SUBJECT + " TEXT" + ")";
public NotesDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_NOTES_TABLE);
}
catch(SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXSISTS topics");
onCreate(db);
}
public void addNote(Note note) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues notes = new ContentValues();
notes.put(NOTE_NAME, note.getNote());
notes.put(NOTE_SUBJECT, note.getSubject());
db.insert(TABLE_NOTES, null, notes);
db.close();
}
public void removeNote(Note note) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NOTES, NOTE_NAME + " = ?",
new String[] {note.getNote()});
db.close();
}
public ArrayList<Note> getNotes(){
ArrayList<Note> notes = new ArrayList<Note>();
String selectQuery = "SELECT * FROM " + TABLE_NOTES;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery(selectQuery, null);
if(cur.moveToFirst()) {
do {
Note note = new Note();
note.setId(Integer.parseInt(cur.getString(0)));
note.setNote(cur.getString(cur.getColumnIndex(NOTE_NAME)));
note.setSubject(cur.getString(cur.getColumnIndex(NOTE_SUBJECT)));
notes.add(note);
} while(cur.moveToNext());
}
db.close();
return notes;
}
public void updateNote(String old_name, String new_name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues topic = new ContentValues();
topic.put(NOTE_NAME, new_name);
db.update(TABLE_NOTES, topic, NOTE_NAME + " = ?",
new String[] {old_name});
db.close();
}
}
Note.java -
public class Note {
String _Note;
int _id;
String subject;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public Note() {
}
public Note(int id, String Note, String Subject) {
this._id = id;
this._Note = Note;
this.subject = Subject;
}
public Note(String Note, String Subject) {
this._Note = Note;
this.subject = Subject;
}
public Note(String Note) {
this._Note = Note;
}
public String getNote() {
return _Note;
}
public void setNote(String _Note) {
this._Note = _Note;
}
public int getId() {
return _id;
}
public void setId(int _id) {
this._id = _id;
}
}
NotesDatabase.java -
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Notes_page extends Activity {
ArrayList<Note> notes = new ArrayList<Note>();
NotesDatabase ndb = new NotesDatabase(this);
private NoteAdapter adapter;
private ListView notes_list;
private TextView subject_display;
String subject;
int requestCode = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notes_page);
notes_list = (ListView) findViewById(R.id.notes);
ndb.getWritableDatabase();
notes = ndb.getNotes();
adapter = new NoteAdapter(this, notes);
subject = getIntent().getStringExtra("SUBJECT_NAME");
notes_list.setAdapter(adapter);
subject_display = (TextView) findViewById(R.id.subject_name);
subject_display.setText(subject);
}
public void onClickAddNewNote(View v) {
startActivityForResult(new Intent("com.Swap.Add_New_Note"), requestCode);
}
public void onActivityResult(int request_Code, int result_Code, Intent i) {
if(request_Code == requestCode) {
if(result_Code == RESULT_OK) {
Note mNote = new Note(i.getStringExtra("NOTE"), getIntent().getStringExtra("SUBJECT_NAME"));
ndb.getWritableDatabase();
ndb.addNote(mNote);
Log.d("AddNote", "Note Succesfully Added to Database");
adapter.add(mNote);
adapter.notifyDataSetChanged();
Toast.makeText(getBaseContext(), mNote.getNote(), Toast.LENGTH_SHORT).show();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_notes_page, menu);
return true;
}
}
Here's the LogCat Error log -
04-13 22:17:10.766: E/linker(25692): load_library(linker.cpp:759): library "libmaliinstr.so" not found
04-13 22:17:14.816: E/CursorWindow(25692): Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 2 columns.
04-13 22:17:14.869: E/AndroidRuntime(25692): FATAL EXCEPTION: main
04-13 22:17:14.869: E/AndroidRuntime(25692): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Swap.RR/com.Swap.RR.Notes_page}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2416)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread.access$600(ActivityThread.java:174)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1382)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.os.Handler.dispatchMessage(Handler.java:107)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.os.Looper.loop(Looper.java:194)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread.main(ActivityThread.java:5409)
04-13 22:17:14.869: E/AndroidRuntime(25692): at java.lang.reflect.Method.invokeNative(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692): at java.lang.reflect.Method.invoke(Method.java:525)
04-13 22:17:14.869: E/AndroidRuntime(25692): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-13 22:17:14.869: E/AndroidRuntime(25692): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
04-13 22:17:14.869: E/AndroidRuntime(25692): at dalvik.system.NativeStart.main(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692): Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.database.CursorWindow.nativeGetString(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.database.CursorWindow.getString(CursorWindow.java:434)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
04-13 22:17:14.869: E/AndroidRuntime(25692): at com.Swap.RR.NotesDatabase.getNotes(NotesDatabase.java:78)
04-13 22:17:14.869: E/AndroidRuntime(25692): at com.Swap.RR.Notes_page.onCreate(Notes_page.java:41)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.Activity.performCreate(Activity.java:5122)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1146)
04-13 22:17:14.869: E/AndroidRuntime(25692): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2328)
04-13 22:17:14.869: E/AndroidRuntime(25692): ... 11 more
Please help me figure out what's wrong with me code. Thanks in advance!!
Your subject line is misleading. The exception in your stacktrace says
Couldn't read row 0, col -1 from CursorWindow
which essentially means that getColumnIndex()
could not find the specified column in the Cursor
and -1 was returned as column index.
Your selection SELECT *
contains all columns from the table.
Your CREATE TABLE
seems to contain all columns you're requesting the index of with getColumnIndex()
in getNotes()
.
Chances are that you've added a column but the test device still has a database file without that column. Just uninstall your app or clear its data to remove the old database file and make your onCreate()
recreate the database on the next run.