3

I am using sqlite in my android app for handling my sessions. I want user to register and then after login goes to profile and show some of db items in the profile. android studio keeps showing this:Unable to start activity ComponentInfo{com.example.neshat.bluedot/com.example.neshat.bluedot.profile}: java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

I checked similar questions and none of them was my answer. I copied related codes for you . this is my sqlitehandlre:

@Override
public void onCreate(SQLiteDatabase db)
{
    String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_USER + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
            + KEY_EMAIL + " TEXT UNIQUE," + KEY_TOTALPOINTS + "TEXT," + KEY_DIGIPOINTS + "TEXT,"  + KEY_UID + " TEXT,"
            + KEY_CREATED_AT + " TEXT" + ");";
    db.execSQL(CREATE_LOGIN_TABLE);

    Log.d(TAG, "Database tables created");
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER);

    // Create tables again
    onCreate(db);
}

/**
 * Storing user details in database
 * */                  //      db.addUser(name, email,totalpoints, digipoints, uid, created_at);

public void addUser(String name, String email ,String totalpoints, String digipoints , String uid, String created_at) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_NAME, name); // Name
    values.put(KEY_EMAIL, email); // Email
    values.put(KEY_TOTALPOINTS, totalpoints);
    values.put(KEY_DIGIPOINTS, digipoints);
    values.put(KEY_UID, uid);
    values.put(KEY_CREATED_AT, created_at); // Created At

    // Inserting Row
    long id = db.insert(TABLE_USER, null, values);
    db.close(); // Closing database connection

    Log.d(TAG, "New user inserted into sqlite: " + id);
}

/**
 * Getting user data from database
 * */
public HashMap<String, String> getUserDetails() {
    HashMap<String, String> user = new HashMap<String, String>();
    String selectQuery = "SELECT  * FROM " + TABLE_USER;

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
    // Move to first row
    cursor.moveToFirst();
    if (cursor.getCount() > 0) {
        user.put("name", cursor.getString(1));
        user.put("email", cursor.getString(2));
        user.put("totalpoints", cursor.getString(3));
        user.put("digipoints", cursor.getString(4));
        user.put("uid", cursor.getString(5));
        user.put("created_at", cursor.getString(6));
    }
    cursor.close();
    db.close();
    // return user
    Log.d(TAG, "Fetching user from Sqlite: " + user.toString());

    return user;
}

and this is my registeractivity

private void registerUser(final String name, final String email, final String password)
{
    // Tag used to cancel the request
    String tag_string_req = "req_register";

    pDialog.setMessage("Registering ...");
    showDialog();

    StringRequest strReq = new StringRequest(Method.POST, AppConfig.URL_REGISTER, new Response.Listener<String>() {

        @Override
        public void onResponse(String response) {
            Log.d(TAG, "Register Response: " + response.toString());
               Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_LONG).show();

            hideDialog();

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error)
                {
                    // User successfully stored in MySQL
                    // Now store the user in sqlite
                    String uid = jObj.getString("uid");

                    JSONObject user = jObj.getJSONObject("user");
                    String name = user.getString("name");
                    String email = user.getString("email");
                    String totalpoints = user.getString("totalpoints");
                    String digipoints = user.getString("digipoints");
                    String created_at = user.getString("created_at");

                    Log.d("sqlite", uid);
                    Log.d("sqlite", name);
                    Log.d("sqlite", email);
                    Log.d("sqlite", totalpoints);
                    Log.d("sqlite", digipoints);
                    Log.d("sqlite", created_at);

                    // Inserting row in users table
                    db.addUser(name, email,totalpoints, digipoints, uid, created_at);

                    Toast.makeText(getApplicationContext(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();

                    // Launch login activity
                    Intent intent = new Intent(
                            RegisterActivity.this,
                            LoginActivity.class);
                    startActivity(intent);
                    finish();
                } else
                {

                    // Error occurred in registration. Get the error
                    // message
                    String errorMsg = jObj.getString("error_msg");
                    Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
                    Log.d("Debug", errorMsg);

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e(TAG, "Registration Error: " + error.toString());
            Toast.makeText(getApplicationContext(),
                    error.getMessage(), Toast.LENGTH_LONG).show();
            hideDialog();
        }

and this is my profile activity :

 db = new SQLiteHandler(getApplicationContext());

    // session manager
    session = new SessionManager(getApplicationContext());
    txtName = (TextView) findViewById(R.id.name);
    pointsview = (TextView) findViewById(R.id.points);

    //txtEmail = (TextView) findViewById(R.id.email);
    btnLogout = (Button) findViewById(R.id.lgot);
    if (!session.isLoggedIn())
    {
        logoutUser();
    }

    //Fetching user details from sqlite
    HashMap<String, String> user = db.getUserDetails();

    String name = user.get("name");
    String email = user.get("email");
    String tpoints = user.get("totalpoints");
    String dpoints = user.get("digipoints");

    // Displaying the user details on the screen
    txtName.setText(name);
    pointsview.setText(tpoints);

and this is my logcat:

  mple.neshat.bluedot E/CursorWindow﹕ Failed to read row 0, column 5 from a CursorWindow which has 2 rows, 5 columns.
01-24 05:59:22.362  11101-11101/com.example.neshat.bluedot D/AndroidRuntime﹕ Shutting down VM
01-24 05:59:22.362  11101-11101/com.example.neshat.bluedot E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.neshat.bluedot, PID: 11101
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.neshat.bluedot/com.example.neshat.bluedot.profile}: java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
            at android.database.CursorWindow.nativeGetString(Native Method)
            at android.database.CursorWindow.getString(CursorWindow.java:438)
            at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
            at com.example.neshat.bluedot.helper.SQLiteHandler.getUserDetails(SQLiteHandler.java:101)
            at com.example.neshat.bluedot.profile.onCreate(profile.java:130)
            at android.app.Activity.performCreate(Activity.java:5933)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Edit: I replaced user.put("name", cursor.getString(1)); with user.put("name", cursor.getString(cursor.getColumnIndex("name")))

but my error has changed to :

Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at com.example.neshat.bluedot.helper.SQLiteHandler.getUserDetails(SQLiteHandler.java:100)
        at com.example.neshat.bluedot.profile.onCreate(profile.java:130)

error is on totalpoints column and i cannot understand why.

user3696174
  • 123
  • 9

2 Answers2

2

There is no column 5 in the SELECT * result set.

Looks like you have added columns to your CREATE TABLE but you forgot to increment the database version to upgrade it, or uninstall your app to get rid of the old database. See When is SQLiteOpenHelper onCreate() / onUpgrade() run? for more about that.

Note that there are also a couple of whitespace problems in your CREATE TABLE: missing space between column names and types. Fix those before running your code again to not get "no such column" errors on e.g. insertion.

Community
  • 1
  • 1
laalto
  • 150,114
  • 66
  • 286
  • 303
0

Try to use this method from Cursor instead of pass index directly:

/**
 * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
 * If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which
 * will make the error more clear.
 *
 * @param columnName the name of the target column.
 * @return the zero-based column index for the given column name, or -1 if
 * the column name does not exist.
 * @see #getColumnIndexOrThrow(String)
 */
int getColumnIndex(String columnName);

Then you will get something like this:

user.put("email", cursor.getString(cursor.getColumnIndex("email")));

It will probably solve your problem.

Good luck.

Rodrigo Henriques
  • 1,804
  • 1
  • 15
  • 27