Search code examples
javaandroidsqliteandroid-recyclerviewsqliteopenhelper

I am not understanding this error : Couldn't read row 0, col -1 from CursorWindow


While running this code it show below error. These code are the part of my simple project. Here I am fetching JSON data into app and save into SQLiteDatabase(While Internet connected) and after saving data, app show these data as well as internet connection is cut off. Here I provided necessary java classes if other needed I will provided those too.

"DBHelper.java" is the part of Database helper class of app. "DataShow.java" is also the part of Main java class.

Sorry for my poor English.

Error:-

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

DBHelper.java

package csitmnr.newsproject2.DatabaseHelper;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.nfc.NfcEvent;
import android.util.Log;

import java.sql.Blob;
import java.util.ArrayList;
import java.util.List;

import csitmnr.newsproject2.NewsPojo;

import static android.R.attr.id;
import static android.R.attr.theme;
import static android.R.attr.wallpaperCloseEnterAnimation;



public class DatabaseNews extends SQLiteOpenHelper {
  private static final String DATABASE_NAME = "newsandevent.db";
  private static final String TABLE_NAME = "newsandevent";

public DatabaseNews(Context context) {
    super(context, DATABASE_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
    sqLiteDatabase.execSQL("CREATE TABLE " + TABLE_NAME + "(ID INTEGER PRIMARY KEY,TITLE TEXT,INTRO_TXT TEXT,CREATED_BY_ID INTEGER,FEATURED_IMAGE BLOB,DETAIL TEXT,CREATED_AT TEXT,UPDATED_AT TEXT)");


}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

}

public void putData(String title, String intro_text, String detail, String created_at, String updated_at,SQLiteDatabase sqLiteDatabase){

    ContentValues cv = new ContentValues();

    cv.put("TITLE", title);//1
    cv.put("INTRO_TXT", intro_text);//2
    cv.put("DETAIL", detail);//5
    cv.put("CREATED_AT", created_at);//6
    cv.put("UPDATED_AT", updated_at);//7



    long result = sqLiteDatabase.insertOrThrow(TABLE_NAME, null, cv);

}

public Cursor getAllDatas(SQLiteDatabase sqLiteDatabase) {

    String[] alldata = new String[]{"TITLE", "INTRO_TXT", "DETAIL", "CREATED_AT", "UPDATED_AT"};
    Cursor cursor = sqLiteDatabase.query(TABLE_NAME, alldata, null, null, null, null, null);


    return cursor;
}

}

DataShow.java

package csitmnr.newsproject2.Fragments;


import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.JsonObject;
import com.kosalgeek.android.caching.FileCacher;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import csitmnr.newsproject2.Adapter.NewsAdapter;
import csitmnr.newsproject2.ConnectionDetector;
import csitmnr.newsproject2.DatabaseHelper.DatabaseNews;
import csitmnr.newsproject2.NewsPojo;
import csitmnr.newsproject2.R;



public class NewsAndEvents extends Fragment {

NewsAdapter adapter;
ArrayList<NewsPojo> arrayList = new ArrayList<>();
boolean isConn ;
DatabaseNews databaseNews;

public static final String urlNews = "http://alfabeta.bidheegroup.com/api/v1/news";

RecyclerView recyclerView;
List<NewsPojo> newslist = new ArrayList<>();

ProgressDialog progressDialog;


@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    isConn = ConnectionDetector.isConnected(getContext());

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_news_and_events, container, false);

    recyclerView = view.findViewById(R.id.recyclerViewNews);

    databaseNews = new DatabaseNews(getContext());

    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setHasFixedSize(true);

    progressDialog = new ProgressDialog(getContext());
    progressDialog.setMessage("Data is loading... ");
    progressDialog.setCancelable(false);

    if (isConn) {
        getNews();
    } else {

    //            showNews();
        dataShow();

    }

    return view;
        ////get data from database and set to the reycler view ///

}

private void dataShow() {
    DatabaseNews databaseNews =  new DatabaseNews(getContext());
    SQLiteDatabase data = databaseNews.getWritableDatabase();

    Cursor cursor = databaseNews.getAllDatas(data);


    if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst() ){
    do {


        int title = cursor.getColumnIndex("TITLE");
        int intro_text = cursor.getColumnIndex("INTRO_TEXT");
        int detail = cursor.getColumnIndex("DETAIL");
        int created_at = cursor.getColumnIndex("CREATED_AT");
        int updated_at = cursor.getColumnIndex("UPDATED_AT");




        NewsPojo data1 = new NewsPojo(cursor.getString(title),cursor.getString(intro_text),cursor.getString(detail),cursor.getString(created_at),cursor.getString(updated_at));
        arrayList.add(data1);


    }while (cursor.moveToNext());
    cursor.close();

    adapter = new NewsAdapter(arrayList);
    recyclerView.setAdapter(adapter);
}
}

private void getNews() {
    progressDialog.show();

    final SQLiteDatabase sqLiteDatabase = databaseNews.getWritableDatabase();

    StringRequest request = new StringRequest(urlNews, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            progressDialog.hide();
            try {
                JSONObject object = new JSONObject(response);


                JSONArray jsonArray = object.getJSONArray("data");


                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject obj = jsonArray.getJSONObject(i);

                    Integer id = obj.getInt("id");
                    String title = obj.getString("title");
                    String intro_text = obj.getString("intro_text");
                    Integer created_by_id = obj.getInt("created_by_id");
                    String featured_image = obj.getString("featured_image");
                    String detail = obj.getString("detail");
                    String created_at = obj.getString("created_at");
                    String updated_at = obj.getString("updated_at");

                    NewsPojo data = new NewsPojo(id, title, intro_text, created_by_id, featured_image, detail, created_at, updated_at);

                    DatabaseNews databaseNews = new DatabaseNews(getContext());
                    SQLiteDatabase sqLiteDatabase1 = databaseNews.getWritableDatabase();
                    databaseNews.putData(title,intro_text,detail,created_at,updated_at,sqLiteDatabase);

                    arrayList.add(data);


                }
            } catch (JSONException e) {

                e.printStackTrace();
            }


            NewsAdapter adapter = new NewsAdapter(arrayList);
            recyclerView.setAdapter(adapter);

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            progressDialog.hide();
            Toast.makeText(getContext(), error.toString(), Toast.LENGTH_SHORT).show();

        }
    });

    RequestQueue queue = Volley.newRequestQueue(getContext());
    queue.add(request);


}

}

NewsPojo.java

package csitmnr.newsproject2;

import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class NewsPojo implements Serializable {

    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("intro_text")
    @Expose
    private String introText;
    @SerializedName("created_by_id")
    @Expose
    private Integer createdById;
    @SerializedName("featured_image")
    @Expose
    private String featuredImage;
    @SerializedName("detail")
    @Expose
    private String detail;
    @SerializedName("created_at")
    @Expose
    private String createdAt;
    @SerializedName("updated_at")
    @Expose
    private String updatedAt;

    public NewsPojo(String title, String introText, String detail, String createdAt, String updatedAt) {
        this.title = title;
        this.introText = introText;
        this.detail = detail;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }

    public NewsPojo(Integer id, String title, String introText, Integer createdById, String featuredImage, String detail, String createdAt, String updatedAt) {
        this.id = id;
        this.title = title;
        this.introText = introText;
        this.createdById = createdById;
        this.featuredImage = featuredImage;
        this.detail = detail;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getIntroText() {
        return introText;
    }

    public void setIntroText(String introText) {
        this.introText = introText;
    }

    public Integer getCreatedById() {
        return createdById;
    }

    public void setCreatedById(Integer createdById) {
        this.createdById = createdById;
    }

    public String getFeaturedImage() {
        return featuredImage;
    }

    public void setFeaturedImage(String featuredImage) {
        this.featuredImage = featuredImage;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

    public String getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(String updatedAt) {
        this.updatedAt = updatedAt;
    }
}

Solution

  • This exception is usually happening because getColumnIndex() returns -1 when it does not find the column in a cursor, and attempting to retrieve data from column index -1 is an error.

    Note that you have

    INTRO_TXT TEXT
    

    in CREATE TABLE and later

    int intro_text = cursor.getColumnIndex("INTRO_TEXT");
    

    Make sure your column names are consistent. Using constants rather than raw strings is one easy way to do so.