Search code examples
javaandroidandroid-sqliteandroid-cursor

java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow


Guys.

I have a database in my app.

The database is created programmatically.

I wanted to get the data from the database and it returns the column index is -1.

There is a data in the db, but the column index is -1 and I can't return the data.

How to solve this?

Here is my code;

The code adding items to the db.

String task = "cook lunch";

helper = new TaskDBHelperHome(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();

ContentValues values = new ContentValues();

values.clear();
values.put("task", task);

db.insertWithOnConflict(TaskContractHome.TABLE, null, values,
        SQLiteDatabase.CONFLICT_IGNORE);

And the code showing the data.

helper = new TaskDBHelperHome(mcontext);
    SQLiteDatabase homeDB = helper.getReadableDatabase();
    Cursor cursor = homeDB.rawQuery("SELECT COUNT(*) FROM hometasks", null);

    cursor.moveToFirst();
    if (cursor != null && cursor.moveToFirst()) {
        if (cursor.getInt(0) == 1) {

            cursor.moveToFirst();
            Integer indexnum = cursor.getColumnIndex("task");

            String index = Integer.toString(cursor.getColumnIndex("task"));

            String hometodo = cursor.getString(indexnum);

            Log.d("DatabaseTodoListManager", "Your to-do is " + hometodo);

            //expected to return the data "cook lunch",
            //but shows the error java.lang.IllegalStateException

            cursor.close();
        }
    }

TaskDBHelperHome.java

public class TaskDBHelperHome extends SQLiteOpenHelper {

    public TaskDBHelperHome(Context context) {
        super(context, TaskContractHome.DB_NAME, null, TaskContractHome.DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqlDB) {
        String sqlQuery =
                String.format("CREATE TABLE %s (" +
                                "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                                "%s TEXT)", TaskContractHome.TABLE,
                        TaskContractHome.Columns.TASK);

        Log.d("TaskDBHelper","Query to form table: "+sqlQuery);
        sqlDB.execSQL(sqlQuery);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqlDB, int i, int i2) {
        sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContractHome.TABLE);
        onCreate(sqlDB);
    }
}

TaskContractHome.java

public class TaskContractHome {
    public static final String DB_NAME = "home";
    public static final int DB_VERSION = 1;
    public static final String TABLE = "hometasks";

    public class Columns {
        public static final String TASK = "task";
        public static final String _ID = BaseColumns._ID;
    }
}

Logcat error for additional info :

E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 1 columns.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.bedrock.live, PID: 14081
E/AndroidRuntime: java.lang.RuntimeException: Unable to start receiver com.bedrock.live.service.WiFiService: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
E/AndroidRuntime:     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2601)
E/AndroidRuntime:     at android.app.ActivityThread.access$1800(ActivityThread.java:144)
E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1370)
E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5238)
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931)
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:726)
E/AndroidRuntime:     at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
E/AndroidRuntime:  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.
E/AndroidRuntime:     at android.database.CursorWindow.nativeGetString(Native Method)
E/AndroidRuntime:     at android.database.CursorWindow.getString(CursorWindow.java:438)
E/AndroidRuntime:     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
E/AndroidRuntime:     at com.bedrock.live.service.WiFiService.homeNotification(WiFiService.java:106)
E/AndroidRuntime:     at com.bedrock.live.service.WiFiService.count(WiFiService.java:82)
E/AndroidRuntime:     at com.bedrock.live.service.WiFiService.Wifi(WiFiService.java:64)
E/AndroidRuntime:     at com.bedrock.live.service.WiFiService.onReceive(WiFiService.java:45)
E/AndroidRuntime:     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2594)
E/AndroidRuntime:     at android.app.ActivityThread.access$1800(ActivityThread.java:144) 
E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1370) 
E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102) 
E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135) 
E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5238) 
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method) 
E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372) 
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931) 
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:726) 
E/AndroidRuntime:     at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115) 

Solution

  • You define the cursor like this:

    cursor = homeDB.rawQuery("SELECT COUNT(*) FROM hometasks", null);
    

    The result of the aggregate function COUNT(*) has no column name. So,

    indexnum = cursor.getColumnIndex("task");
    

    assigns '-1' to 'indexnum'.

    The query will only give you an integer value (the number of rows), if you want the value of the "task" column, you need a different query.

    Spoiler:

    Cursor cursor = homeDB.rawQuery("SELECT tasks FROM hometasks", null);