Jeongbebs
Jeongbebs

Reputation: 4120

Couldn't read row 0, col 3 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it

I am having difficulty inserting image in my sqlite database. There are no syntax errors in my code. After I run it, the app automatically force stops. The logcat shows:

Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 3 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

at com.synergy88studios.catalogapp.DatabaseHandler.getAllItemsInList(DatabaseHandler.java:86)

at com.synergy88studios.catalogapp.MainActivity.onCreate(MainActivity.java:56)

Here is my method in getAllItemsInList in my DatabaseHandler.class

public List<Item> getAllItemsInList() {
    List<Item> itemList = new ArrayList<Item>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_ITEMS;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Item item = new Item();
            item.set_id(Integer.parseInt(cursor.getString(0)));
            item.set_name(cursor.getString(1));
            item.set_description(cursor.getString(2));
            item.set_image(cursor.getBlob(3));
            // Adding contact to list
            itemList.add(item);
        } while (cursor.moveToNext());
    }

    // return item list
    return itemList;
}

In my MainActivity, I simply call the method.

items = db.getAllItemsInList();

EDIT

DatabaseHandler.class

public class DatabaseHandler extends SQLiteOpenHelper{
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "CatalogItems";
public static final String TABLE_ITEMS = "Items";

public static final String KEY_ID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_DESC = "description";
public static final String KEY_IMAGE = "image";
public static final String[] ALL_KEYS = new String[] {KEY_ID, KEY_NAME, KEY_DESC};
//private static final String KEY_IMAGE = "image";

public DatabaseHandler(Context context){
    super(context,DATABASE_NAME,null,DATABASE_VERSION);
}

public void onCreate(SQLiteDatabase db){
    String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + "( "
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
            + KEY_DESC + " TEXT, " + KEY_IMAGE + " BLOB" + ")";
    db.execSQL(CREATE_ITEMS_TABLE);
}

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
    db.execSQL("DROP TABLE IF EXISTS "+ TABLE_ITEMS);
    onCreate(db);
}

public void addItems(Item item){
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_NAME, item.get_name());
    values.put(KEY_DESC, item.get_description());
    values.put(KEY_IMAGE, item.get_image());

    db.insert(TABLE_ITEMS, null ,values);
    db.close();
}

Item getItem(int id){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query(TABLE_ITEMS, new String[] { KEY_ID,
                    KEY_NAME, KEY_DESC , KEY_IMAGE}, KEY_ID + "=?",
            new String[] { String.valueOf(id) }, null, null, null, null);
    Item item = new Item(Integer.parseInt(cursor.getString(0)),
            cursor.getString(1), cursor.getString(2),  cursor.getBlob(3));

    return item;
}

void deleteAllItems() {
    SQLiteDatabase db = this.getWritableDatabase();
    db.execSQL("DELETE FROM "+ TABLE_ITEMS);

}

public List<Item> getAllItemsInList() {
    List<Item> itemList = new ArrayList<Item>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_ITEMS;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Item item = new Item();
            item.set_id(Integer.parseInt(cursor.getString(0)));
            item.set_name(cursor.getString(1));
            item.set_description(cursor.getString(2));
            item.set_image(cursor.getBlob(3));
            // Adding contact to list
            itemList.add(item);
        } while (cursor.moveToNext());
    }

    // return item list
    return itemList;
}

public Cursor getAllRows() {
    SQLiteDatabase db = this.getWritableDatabase();
    String where = null;
    Cursor c =  db.query(true, TABLE_ITEMS, ALL_KEYS,
            where, null, null, null, null, null);
    if (c != null) {
        c.moveToFirst();
    }
    return c;
}


public int getItemsCount(){
    String countQuery = "SELECT * FROM " + TABLE_ITEMS;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(countQuery, null);

    return cursor.getCount();

}

public int updateItem(Item item) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_NAME, item.get_name());
    values.put(KEY_DESC, item.get_description());
    values.put(KEY_IMAGE, item.get_image());

    // updating row
    return db.update(TABLE_ITEMS, values, KEY_ID + " = ?",
            new String[] { String.valueOf(item.get_id()) });
}

public void deleteContact(Item item) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_ITEMS, KEY_ID + " = ?",
            new String[] { String.valueOf(item.get_id()) });
    db.close();
 }

}

I hope someone can explain to me what happens. I can post my other classes for reference.

Upvotes: 1

Views: 2194

Answers (1)

laalto
laalto

Reputation: 152817

Don't store large data in an Android sqlite table. In particular, the CursorWindow only supports row data up to 2MB. If your row is larger, you can't access it.

Instead, store your blobs as files in the filesystem and store just the path in database.

Upvotes: 2

Related Questions