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.
I changed android:allowBackup="true" into "False" In android manifest.
public class ListViewActivity extends Activity {
SQLiteHelper SQLITEHELPER;
SQLiteDatabase SQLITEDATABASE;
Cursor cursor;
SQLiteListAdapter ListAdapter;
ArrayList<String> CODE_ArrayList = new ArrayList<String>();
ArrayList<String> ITEM_ArrayList = new ArrayList<String>();
ArrayList<String> QUANTITY_ArrayList = new ArrayList<String>();
ArrayList<String> TAX_ArrayList = new ArrayList<String>();
ArrayList<String> UNITPRICE_ArrayList = new ArrayList<String>();
ArrayList<String> TOTALPRICE_ArrayList = new ArrayList<String>();
ArrayList<String> SELLER_ArrayList = new ArrayList<String>();
ListView LISTVIEW;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
LISTVIEW = (ListView)findViewById(R.id.listView1);
SQLITEHELPER = new SQLiteHelper(this);
}
@Override
protected void onResume() {
ShowSQLiteDBdata();
super.onResume();
}
private void ShowSQLiteDBdata() {
SQLITEDATABASE = SQLITEHELPER.getWritableDatabase();
cursor = SQLITEDATABASE.rawQuery("SELECT * FROM demoTableb", null);
CODE_ArrayList.clear();
ITEM_ArrayList.clear();
QUANTITY_ArrayList.clear();
TAX_ArrayList.clear();
UNITPRICE_ArrayList.clear();
TOTALPRICE_ArrayList.clear();
SELLER_ArrayList.clear();
if (cursor.moveToFirst()) {
do {
CODE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Codes)));
ITEM_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Item)));
QUANTITY_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Quantity)));
TAX_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Tax)));
UNITPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Unitprice)));
TOTALPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Totalprice)));
SELLER_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Seller)));
} while (cursor.moveToNext());
}
ListAdapter = new SQLiteListAdapter(ListViewActivity.this,
CODE_ArrayList,
ITEM_ArrayList,
QUANTITY_ArrayList,
TAX_ArrayList,
UNITPRICE_ArrayList,
TOTALPRICE_ArrayList,
SELLER_ArrayList
);
LISTVIEW.setAdapter(ListAdapter);
cursor.close();
}
}
- error is shown in line
ShowSQLiteDBdata();
,andSQLITEDATABASE = SQLITEHELPER.getWritableDatabase();
This is EditDataActivity
public class EditDataActivity extends Activity {
Button next, previous, update, delete;
EditText item,quantity,tax,unitprice,totalprice,seller;
SQLiteDatabase SQLITEDATABASE, SQLITEDATABASE2;
String GetSQliteQuery, UpdateRecordQuery, DeleteQuery ;
Cursor cursor, cursorCheckDataIsEmptyOrNot ;
TextView purchase;
Boolean CheckEditTextEmpty;
String Item,Quantity,Tax,Unitprice,Totalprice,Seller;
int ItemCode ;
String ConvertCode ;
SQLiteHelper SQLITEHELPER;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_data);
next = (Button)findViewById(R.id.button1);
previous = (Button)findViewById(R.id.button2);
update = (Button)findViewById(R.id.button3);
delete = (Button)findViewById(R.id.button4);
item = (EditText)findViewById(R.id.editText2);
quantity = (EditText)findViewById(R.id.editText3);
tax = (EditText)findViewById(R.id.editText4);
unitprice = (EditText)findViewById(R.id.editText5);
totalprice = (EditText)findViewById(R.id.editText6);
seller = (EditText)findViewById(R.id.editText7);
purchase = (TextView)findViewById(R.id.textview1);
GetSQliteQuery = "SELECT * FROM demoTableb" ;
SQLITEDATABASE = openOrCreateDatabase("DemoDataBaseb", Context.MODE_PRIVATE, null);
cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
cursor.moveToFirst();
GetSQLiteDatabaseRecords();
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!cursor.isLast()){
cursor.moveToNext();
}
GetSQLiteDatabaseRecords();
}
});
previous.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!cursor.isFirst()){
cursor.moveToPrevious();
}
GetSQLiteDatabaseRecords();
}
});
update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Item = item.getText().toString();
Quantity = quantity.getText().toString();
Tax = tax.getText().toString();
Unitprice = unitprice.getText().toString();
Totalprice = totalprice.getText().toString();
Seller = seller.getText().toString();
ConvertCode = purchase.getText().toString();
ItemCode = Integer.parseInt(ConvertCode);
UpdateRecordQuery = "UPDATE demoTableb SET Item ='" + Item + "', Quantity ='" + Quantity + "' ,Tax = '"+Tax+"',Unitprice = '"+Unitprice+"',Totalprice = '"+Totalprice+"',Seller ='"+Seller+"' WHERE Code=" + ItemCode + ";";
CheckEditTextIsEmptyOrNot(Item,Quantity,Tax,Unitprice,Totalprice,Seller );
if (CheckEditTextEmpty == false) {
SQLITEDATABASE.execSQL(UpdateRecordQuery);
cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
cursor.moveToPosition(ItemCode);
Toast.makeText(EditDataActivity.this,"Data Updated Successfully", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(EditDataActivity.this,"Please Fill All the Fields", Toast.LENGTH_LONG).show();
}
}
});
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ConvertCode = purchase.getText().toString();
ItemCode = Integer.parseInt(ConvertCode);
DeleteQuery = "DELETE FROM demoTableb WHERE Code=" + ItemCode + ";";
SQLITEDATABASE.execSQL(DeleteQuery);
Toast.makeText(EditDataActivity.this, "Record Deleted Successfully", Toast.LENGTH_LONG).show();
cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
}
});
}
public void GetSQLiteDatabaseRecords(){
purchase.setText(cursor.getString(0).toString());
item.setText(cursor.getString(1).toString());
quantity.setText(cursor.getString(2).toString());
tax.setText(cursor.getString(3).toString());
unitprice.setText(cursor.getString(4).toString());
totalprice.setText(cursor.getString(5).toString());
seller.setText(cursor.getString(6).toString());
}
public void CheckEditTextIsEmptyOrNot (String Item, String Quantity, String Tax, String Unitprice, String Totalprice,String Seller){
if( TextUtils.isEmpty(Item) || TextUtils.isEmpty(Quantity)|| TextUtils.isEmpty(Tax)|| TextUtils.isEmpty(Unitprice)|| TextUtils.isEmpty(Totalprice) || TextUtils.isEmpty(Seller)){
CheckEditTextEmpty = true ;
}
else {
CheckEditTextEmpty = false ;
}
}
}
and this is the mainactivity
public class SecondActivity extends Activity {
EditText code,item,quantity,tax,unitprice,totalprice,seller ;
Button Submit, EditData, DisplayData;
SQLiteDatabase SQLITEDATABASE;
String Codes,Item,Quantity,Tax,Unitprice,Totalprice,Seller ;
Boolean CheckEditTextEmpty ;
String SQLiteQuery ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.purchase);
code = (EditText)findViewById(R.id.edtcd);
item = (EditText)findViewById(R.id.edtitm);
quantity= (EditText)findViewById(R.id.edtqty);
tax = (EditText) findViewById(R.id.edttax);
unitprice = (EditText) findViewById(R.id.edtprc);
totalprice = (EditText) findViewById(R.id.edttp);
seller = (EditText) findViewById(R.id.edtslr);
Submit = (Button)findViewById(R.id.sbt);
EditData = (Button)findViewById(R.id.edt);
DisplayData = (Button)findViewById(R.id.dply);
Submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
DBCreate();
SubmitData2SQLiteDB();
}
});
EditData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(getApplicationContext(),EditDataActivity.class);
startActivity(i);
}
});
DisplayData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(SecondActivity.this,ListViewActivity.class);
startActivity(i);
}
});
}
public void DBCreate(){
SQLITEDATABASE = openOrCreateDatabase("DemoDataBaseb", Context.MODE_PRIVATE, null);
SQLITEDATABASE.execSQL("CREATE TABLE IF NOT EXISTS demoTableb(Code INTEGER PRIMARY KEY , item INTEGER,quantity INTEGER, tax INTEGER,Unitprice INTEGER,Totalprice INTEGER,Seller VARCHAR);");
}
public void SubmitData2SQLiteDB(){
Codes = code.getText().toString();
Item = item.getText().toString();
Quantity = quantity.getText().toString();
Tax = tax.getText().toString();
Unitprice = unitprice.getText().toString();
Totalprice = totalprice.getText().toString();
Seller = seller.getText().toString();
CheckEditTextIsEmptyOrNot( Codes,Item,Quantity,Tax,Unitprice,Totalprice,Seller);
if(CheckEditTextEmpty == true)
{
SQLiteQuery = "INSERT INTO demoTableb (code,item,quantity,tax,unitprice,totalprice,seller) VALUES('"+Codes+"', '"+Item+"','"+Quantity+"','"+Tax+"','"+Unitprice+"','"+Totalprice+"', '"+Seller+"');";
SQLITEDATABASE.execSQL(SQLiteQuery);
Toast.makeText(SecondActivity.this,"Data Submit Successfully", Toast.LENGTH_LONG).show();
ClearEditTextAfterDoneTask();
}
else {
Toast.makeText(SecondActivity.this,"Please Fill All the Fields", Toast.LENGTH_LONG).show();
}
}
public void CheckEditTextIsEmptyOrNot(String code, String item, String quantity, String tax, String Name, String PhoneNumber, String subject){
if(TextUtils.isEmpty(Codes) || TextUtils.isEmpty(Item) || TextUtils.isEmpty(Quantity) || TextUtils.isEmpty(Tax) || TextUtils.isEmpty(Unitprice) || TextUtils.isEmpty(Totalprice) || TextUtils.isEmpty(Seller)){
CheckEditTextEmpty = false ;
}
else {
CheckEditTextEmpty = true ;
}
}
public void ClearEditTextAfterDoneTask(){
code.getText().clear();
item.getText().clear();
quantity.getText().clear();
tax.getText().clear();
unitprice.getText().clear();
totalprice.getText().clear();
seller.getText().clear();
}
}
public class SQLiteHelper extends SQLiteOpenHelper {
static String DATABASE_NAME="DemoDataBaseb";
public static final String Codes="code";
public static final String TABLE_NAME="demoTableb";
public static final String Item="itm";
public static final String Quantity="qty";
public static final String Tax="tax";
public static final String Unitprice="prc";
public static final String Totalprice="tp";
public static final String Seller="slr";
public SQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase database) {
String CREATE_TABLE="CREATE TABLE IF NOT EXISTS "+TABLE_NAME+" ("+Codes+" INTEGER PRIMARY KEY, "+Item+" VARCHAR, "+Quantity+" INTEGER, "+Tax+" INTEGER,"+Unitprice+" INTEGER,"+Totalprice+" INTEGER,"+Seller+" VARCHAR )";
database.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
}
Additional error
public class MainActivity extends AppCompatActivity {
SuggestedSQLiteHelper dbHelper;
Cursor cursor;
SimpleCursorAdapter sca;
ListView listview1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new SuggestedSQLiteHelper(this);
listview1 = this.findViewById(R.id.listView1);
if (dbHelper.isTableEmpty(SuggestedSQLiteHelper.TABLE_NAME)) {
dbHelper.insertDemoTablebRow("Item1",1,5,100,100,"Fred");
}
setOrRefreshListView();
}
private void setOrRefreshListView() {
cursor = dbHelper.getAllFromDemoTableb();
if (sca == null) {
// setup the adapter
// NOTE CURSOR ADAPTERS MUST HAVE _ID column which MUST be type INTEGER and UNIQUE
// see use of BaseColumns._ID in table create
sca = new SimpleCursorAdapter(this,R.layout.demotableb_layout,cursor,
// The columns FROM which the data is to be retrieved
new String[]{
SuggestedSQLiteHelper.ITEM_COLUMN,
SuggestedSQLiteHelper.QUANTITY_COLUMN,
SuggestedSQLiteHelper.TAX_COLUMN,
SuggestedSQLiteHelper.UNITPRICE_COLUMN,
SuggestedSQLiteHelper.TOTALPRICE_COLUMN,
SuggestedSQLiteHelper.SELLER_COLUMN
},
// The id of the view's to display the data as per the layout (2nd parm)
new int[]{
R.id.item,
R.id.quantity,
R.id.tax,
R.id.unitprice,
R.id.totalprice,
R.id.seller
},0 // 0 is fine
);
listview1.setAdapter(sca); // Tie the adapter to the ListView
// Can add the Listeners here e.g.
listview1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// DO SOMETHING HERE NOTING
// long l passed (4th parm) is the _id of the clicked item
// hence l can be passed/used as it uniquely identifies the row
// e.g.
Cursor csr = dbHelper.getDemotablebById(l);
DatabaseUtils.dumpCursor(csr);
csr.close();
}
});
} else {
sca.swapCursor(cursor);
}
}
@Override
protected void onResume() {
super.onResume();
setOrRefreshListView(); //<<<<<<<<<< will refresh the listview in case data has changed
}
@Override
protected void onDestroy() {
cursor.close(); //<<<<<<<<< should always close the cursor when done with it
super.onDestroy();
}
}
error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.ListView.setAdapter(android.widget.ListAdapter)’ on a null object reference
at com.allmycode.stac.MainActivity.setOrRefreshListView(MainActivity.java:69)
at com.allmycode.stac.MainActivity.onCreate(MainActivity.java:40)
2
Answers
The issue is that the
getColumnIndex
method, if passed a column name that does not exist in the cursor returns -1 as per :-As such one of the expected columns does not exist in the Cursor and as you are using
SELECT * ....
then the column does not exist in the table demoTableb.You need to make check that the table and extracted columns are compatible. That is either add the missing column to the table or remove the missing column from the columns being extracted from the cursor.
NOTE I believe that the
getColumnIndex
has a bug in that it is (was) case sensitive (it certainly used to be) so the issue could be the case of the column namesIf you are unsure then you may find dumping the Cursor helpful. e.g. you could use:-
Here’s an example of a dumped Cursor :-
From the dump you can see that the columns in the Cursor are:-
You can also see that row’s 0 and 1 were extracted.
ADDITIONAL re the comment :-
I believe that uninstalling and reinstalling has allowed you to move on, that is it would appear that you changed the table to add a column and the
col -1
was then fixed as the table was then changed so the column now exists.Certainly the essence of your code works. To show that it does work I put together a test App by using your SQLiteHelper class without any changes and then extracted the core code from your ListViewActivity and placed it into an activity (MainActivity) as per :-
Result
When the above was run, the App didn’t crash and the log included:-
The dump of the schema (i.e. the contents of sqlite_master)
This confirms the existence of the demoTableb table and the SQL used to create the table
Also included was the dump of the Cursor generated by your Query as per :-
Using Database Inspector (now App Inspection) further confirms that all is as expected :-
Last placing a breaking point on the line
cursor.close();
allows inspection of the populated arrays from the debug window as e.g. :-INTEGER PRIMARY KEY
in conjunction with no value being supplied)As such you original issue has been resolved, probably by uninstalling and re-installing the App as the table had probably been changed.
Ongoing Issues
If you are having ongoing issues (the ListView showing nothing) then that should be another question and if so it will very much depend upon the SQLiteListAdapter class.
Additional
Here’s a work example/demo with a ListView more along the lines of how I would do what you are doing.
Instead of trying to convert a cursor into multiple arrays and then use a ListAdapter, instead it uses a CursorAdpater (SimpleCursorAdapater). Thes are designed to handle data in Cursors and are therefore simpler.
HOWEVER, a Cursor adapter requires a column named _id, so the code column name has been changed accordingly (it could remain as is and an alias extracted as _id).
Code that access the database e.g. the query to get the cursor has been moved to the Helper.
The demo only inserts a single row, but does include an onItemClickListener that gets the clicked row from the database (you wouldn’t do this normally but it shows how simple passing a single value the id can be used in another activity).
To start with a layout to allow all the relevant data (from the user perspective) so demotableb_layout :-
The database helper SuggestedSQLiteHelper :-
Note that the convenience methods insert and query have been used, these write the underlying SQL for you. They also bind data thus protecting against SQL injection.
Please take note of the comments
Last putting it all together in an activity (the equivalent of your ListViewActivity) is MainActivity :-
Result
The demo when run :-
Clicking on an item (only the one in the above) and the log includes:-