Could not read row 0, col -1 from CursorWindow - android

I know this question has been asked a number of times but for some reason I can't solve it.
I am 100% sure that there is no problem in the column name.
This is the table definition:
CREATE TABLE IF NOT EXISTS categories (category_id INTEGER, category_name TEXT, PRIMARY KEY(category_id))
This is the access to the column.
As can be seen I do a small test first to make sure I have the correct column name.
Using the name I print to the LogCat the value of the column in the first row.
It works perfectly. Yet, when passed to the adapter I get the above error.
Cursor mGroupsCursor = _dbHelper.fetchGroup();
getActivity().startManagingCursor(mGroupsCursor);
mGroupsCursor.moveToFirst();
String colName = "category_name";
Log.d("ToratYavneh", "i = " + i + " category_name = " + mGroupsCursor.getString(mGroupsCursor.getColumnIndex(colName)));
ExpandableListView elv = (ExpandableListView) view.findViewById(R.id.list);
MyExpandableListAdapter adapter = new MyExpandableListAdapter(mGroupsCursor, getActivity(),
R.layout.rowlayout_category, // Your row layout for a group
R.layout.rowlayout_sub_category, // Your row layout for a child
new String[] { colName }, // Field(s) to use from group cursor
new int[] {R.id.category_name }, // Widget ids to put group data into
new String[] { "sub_category_name" }, // Field(s) to use from child cursors
new int[] { R.id.sub_category_name }); // Widget ids to put child data into
elv.setAdapter(adapter);
I thought that maybe the problem was in the child but it never reaches getChildrenCursor.
Here is the code for the cursor:
public Cursor fetchGroup() {
String query = "SELECT * FROM categories";
return _database.rawQuery(query, null);
}

Related

Android - populate ListView SQLite, cursor null pointer

I have two tables atm, users and notes. I am trying to retrieve data that belongs to the user. So all data to list must be owned by the original user and shown only to him. I have made my table in Databasehelper.
I have made a new class that controls the notes table. In listNotes() I want to loop through the cursor row and get all data owned by the user. Am I quering it correctly?
// Listing all notes
public Cursor listNotes() {
Cursor c = db.query(help.NOTE_TABLE, new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
db.close();
return c;
}
I then want to display the cursor data collected in a listview
public void populateList(){
Cursor cursor = control.listNotes();
getActivity().startManagingCursor(cursor);
//Mapping the fields cursor to text views
String[] fields = new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE};
int [] text = new int[] {R.id.item_title,R.id.item_body, R.id.item_date};
adapter = new SimpleCursorAdapter(getActivity(),R.layout.list_layout,cursor, fields, text,0);
//Calling list object instance
listView = (ListView) getView().findViewById(android.R.id.list);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
You aren't creating the NOTE_TABLE right.
You miss a space and a comma here
+ COLUMN_DATE + "DATETIME DEFAULT CURRENT_TIMESTAMP"
It has to be
+ COLUMN_DATE + " DATETIME DEFAULT CURRENT_TIMESTAMP,"
There are two issues here:
One is you have missed a comma (after the Timestamp as specified in an earlier answer).
The other error you have is when using a SimpleCursorAdapter, you need to ensure that the Projection string array includes something to index the rows uniquely and this must be an integer column named as "_id". SQLite already has a feature built in for this and provides a column named "_id" for this purpose (however you can have your own integer column which you can rename to _id). To solve this, change your projection string array to something like:
new String[] {"ROW_ID AS _id", help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}
I guess the NullPointerException stems from this (but without the stacktrace I don't know for sure).

Android, Database count for each record

I have a ListView in my Class which will display a list of every category in the database table. In that list view I have three TextViews, ROWID CategoryName and CategoryCount respectively as so:
private void populateCategoryList() {
DatabaseHandler db = new DatabaseHandler(this);
TextView tvCategoryItem = (TextView) findViewById(R.id.tvCategoryItem);
TextView tvCatID = (TextView) findViewById(R.id.tvCatID);
TextView tvCatCount = (TextView) findViewById(R.id.tvCatCount);
Cursor cursor = db.getCategories();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
// startManagingCursor(cursor); //TODO Turned off because on back from contact details made a closed cursor error
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[] { db.KEY_ROWID, db.KEY_CATEGORY };
int[] toViewIDs = new int[] { R.id.tvCatID, R.id.tvCategoryItem };
SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(this, // Context
R.layout.item_categorylist, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
/****** COUNT CODE ******/
// tvCatCount = (db.countCategory(category));
// Set the adapter for the list view
lvCategories = (ListView) findViewById(R.id.lvCategories);
lvCategories.setAdapter(myCursorAdapter);
db.close();
You can see in the toFields above that I do not yet have a field set for the count. I will use tvCatCount for this. The question is, how and where do I insert the count code. In this case the count? I think that the countCategory will need to be a for loop where it should get the id of the current category entry for that row, call the db.countCategory and tehn set the value in the TextView to the returned result?
Here is the db.countCategory code:
public int countCategory(category){
SQLiteDatabase db = this.getWritableDatabase();
String[] categoryColumns = new String[] { KEY_ROWID, KEY_CATEGORY };
Cursor c = db.query(CATEGORY_TABLE, null, null, null, KEY_CATEGORY + "=" + category, null, null);
int result = c.getCount();
c.close();
Log.i("DATABASE", "Category Count for id " + id + "is " + result);
return result;
}
which should count every entry in the table equal to the value of "id". This code already works elsewhere, so I am not too worried about it, but to count for each row in a listview, that is a different animal.
To show the count of expenses for each category, you would need a table with these columns:
_id | CategoryName | Count
To compute this, you have to join the categories table to the expenses table, and use GROUP BY to get one output row for each distinct category value:
SELECT Category.rowid AS _id,
Category.Name,
COUNT(*) AS NumberOfExpenses
FROM Category
JOIN Expenses ON Category.rowid = Expenses.CategoryID
GROUP BY Category.rowid

want to save corresponding id in another table...how to use both id and value both in lables?

//all judge name
in label's we get different judge-name from judge table in index of get indexes of judge-name means ids....
Code :
public List<String> getAlljudge(){
List<String> labels = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT " + KEY_ID_JUDGE + "," +KEY_NAME_JUDGE + " FROM " + TABLE_CONTACTS_JUDGE;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
labels.indexOf(cursor.getString(0));
labels.add(cursor.getString(1));
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
db.close();
// returning lables
return labels;
}
further in another table i want to store this id's and selection of judge name through drop down.. actually another layout where a spinner is used where spinner data comes from this "labels" when selection of any judge i want to save corresponding id in another table...how to use both id and value both in labels???? help me...
Pass labels via Intent
Intent ipass = new Intent(this,Your next Class);
ipass.putStringArrayListExtra("key", labels);
startActivity(ipass);
Then In that layout
List<String> labels = new ArrayList<String>();
Intent iget = getIntent();
labels = iRes.getStringArrayListExtra("key");
Hope it work
For spinner operation use this http://www.mkyong.com/android/android-spinner-drop-down-list-example/

Keep bouncing between errors, can't find good fix for Spinner/Adapter

I can't seem to figure out this SimpleCursorAdapter, every time I fix one error, another one pops up and if I follow the steps to fix that one, the first one comes up again. I feel like I'm going in circles here, so here's the chunk of code I'm trying to debug, note, the first part is just creating the DB, but I figured anything could be helpful in figuring it out.
SQLiteDatabase rpgDB = null;
String classFields = " (classID, className, classHP)";
try {
rpgDB = this.openOrCreateDatabase("RpgDB", MODE_PRIVATE, null);
rpgDB.execSQL("DROP TABLE IF EXISTS " + classTable);
rpgDB.execSQL("CREATE TABLE IF NOT EXISTS " + classTable + " (classID INT(3), className TEXT, classHP INT(4));");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (1, 'Warrior', 10);");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (2, 'Rogue', 7);");
rpgDB.execSQL("INSERT INTO " + classTable + classFields + " VALUES (3, 'Mage', 5);");
String query = "SELECT className AS _id FROM " + classTable;
Cursor cursor = rpgDB.rawQuery(query, null);
rpgDB.close();
int[] to = new int[] { R.id.classDropDown };
String[] spinnerFields = new String[] { "_id" };
/**
* Test code to check value of cursor
*/
int count = cursor.getCount();
cursor.moveToFirst();
while (cursor.isAfterLast() == false)
{
String test = cursor.getString(0);
cursor.moveToNext();
}
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.main, cursor, spinnerFields, to);
int cursorcount = cursorAdapter.getCount();
// cursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner classDropDown = (Spinner) this.findViewById(R.id.classDropDown);
classDropDown.setAdapter(cursorAdapter);
} catch (Exception ex) {
System.out.println("Exception: " + ex);
}
Populating a Spinner from a SimpleCursorAdapter seems to be ridiculously troublesome.
EDIT: The error with this code is
Invalid statement in fill window
If I comment out the rpgDB.close() line
Spinner is not a view that can be bounds by this SimpleCursorAdapter
If I change the select statement and spinnerfields to (with the DB commented out):
String query = "SELECT className FROM " + classTable;
String[] spinnerFields = new String[] { "className" };
I get:
column '_id' does not exist
EDIT XML: Here is the main.xml (also id main) XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/white" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="11pt"
android:text="#string/hello"
android:textColor="#color/baseTextColor" />
<Spinner
android:id="#+id/classDropDown"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
EXPLANATION: So if anyone comes upon this in the future, thanks to Luksprog, I understand this a bit better (and he showed me the fixes):
The android.R.id and android.R.layout "ids/layouts" are default xml layouts for Android components such as a TextField and Spinner "list" layouts. The Spinner object is basically NOT complete on its own. You need another XML portion to define how the list itself looks and another one for the lines (the text1 is a default android TextField).
So in short, assign your "to" field to a TextField or use one of the default Android ones such as android.id.text1, but in order to use that I believe you also have to use the layout that CONTAINS the default android field, andoid.R.layout (in my case, simple_spinner_item). Lastly, set the dropdownresource to your own xml or an android default (mine was android.R.layout.simple_spinner_dropdown_item).
Check this:
String query = "SELECT _id, className FROM " + classTable;
Cursor cursor = rpgDB.rawQuery(query, null);
int[] to = new int[] { android.R.id.text1 };
String[] spinnerFields = new String[] { "className"};
SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner, cursor, spinnerFields, to);
cursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner classDropDown = (Spinner) this.findViewById(R.id.classDropDown);
classDropDown.setAdapter(cursorAdapter);
Invalid statement in fill window
You can't close the database connection if you want to pull data from that Cursor.
Spinner is not a view that can be bounds by this SimpleCursorAdapter
The to int array represents the ids of the Views from the row layout file that you pass to the SimpleCursorAdapter to bind data from the from array (R.layout.main, I hope that you do have a layout file and just pass the activity's layout). The id R.id.classDropDown that you used there represents a Spinner view and a SimpleCursorAdapter doesn't know how to bind data to that(it can bind data to a TextView or ImageView). If you want a Spinner on each row(do you really want this? or do you want the default spinner row layout?) then use a custom adapter or a SimpleCursorAdapter.ViewBinder.
column '_id' does not exist
Because you don't have a column with this name in the table classTable. This column should be declared like:
INTEGER PRIMARY KEY AUTOINCREMENT
Maybe you can check this simple tutorial for Spinners.

Android SQLite column value does not exists issue

need help in some wired problem. I have a sqlite table items as following
item_id item_name
1 first
2 second
3 third
and so on
this piece of code is inserting item_id and item_name to arrays perfectly fine. But when i assign it to CustomCursorAdapter it through exception
"column 'first' does not exists"
please help I am newbie to Android.
c = db.rawQuery("select item_id as _id, item_name from items", null);
int i = 0;
c.moveToFirst();
do {
from[i] = c.getString(1);
to[i] = c.getInt(0);
Log.i("item ", to[i] + " " + from[i]);
i++;
} while (c.moveToNext());
try {
CustomCursorAdapter ca = new CustomCursorAdapter(this,
android.R.layout.simple_list_item_1, c, from, to);
getListView().setAdapter(ca);
} catch (Exception e) {
Log.e("Ex ", e.getMessage()); // exception : column 'first' does not exists.
}
This is because you are setting from[0] = c.getString(1).
getString() is zero-based so in your case is returning "first". Then you are passing from as the from parameter of a class (that I guess, extends SimpleCursorAdapter) and then you are receiving this error when the adapter is trying to map this column name. In this case from represents the list of column names holding the data to bind to the UI, which is represented by to.
in from parameter in
CustomCursorAdapter ca = new CustomCursorAdapter(this,
android.R.layout.simple_list_item_1, c, from, to);
needed column names as arguments, whereas you are passing column values array to from array, whereas 'to' needed to be id of textviews of layouts these columns to de projected, so in this example id is android.R.id.textview1, so do following:
String[] from= new String[]{"item_name"};
int[] to= new int[]{android.R.id.textView1};
and then execute your query on these parameters.

Categories

Resources