Android cursor headaches - android

Could someone please help me to understand why the following block of code keeps throwing this error? It's driving me crazy trying to debug this.
public int getContactsCountByGroupId(int id) {
Cursor c = db.rawQuery("SELECT COUNT(*) AS total FROM msg_group_lu WHERE group_id = ?", new String[] {String.valueOf(id)});
DatabaseUtils.dumpCursor(c);
int retval = c.getInt(c.getColumnIndex("total"));
return retval;
}
The dump seems to indicate this;
0 {
total=0
}
This is telling me that there is data in column 0, but yet everytime it tries to execute the line with this code;
int retval = new Integer(c.getInt(c.getColumnIndex("total")));
It gives me this error;
CursorIndexOutOfBoundsException: Index -1 requested, with size of 1
I have tried everything I can think of to try to fix this and am completely stumped. :(
I hope someone knows what causes this.

try writing c.moveToNext(); before executing the line
int retval = c.getInt(c.getColumnIndex("total"));
The cursor position is now -1. after executing the moveToNext command it comes to 0th position.

Related

Cursor Index out o fBounds Exception :Index 11 requested, with a size of 11

I faced one issue randomly whenever try to get the getSelectedCustomerPhone() then randomly cursor index out of Bound Exception will appear.
Is there anything wrong with this code?. I could not find the bug.
private String getSelectedCustomerPhone() {
myCursor.moveToPosition(selectedCustPosition);
String phone =
myCursor.getString(myCursor.getColumnIndex("cust_phone"));
if (phone != null) return phone;
return "";
}
It seems that selectedCustPosition is outside of the cursor range [0, Cursor.getCount() - 1]. Try understanding why it happens.
As a workaround to prevent the crash, you can add a check
if (0 <= selectedCustPosition && selectedCustPosition < myCursor.getCount()) {
myCursor.moveToPosition(selectedCustPosition);
// ...
}
But this is only a workaround that will more likely return incorrect phone number. Better to understand the real problem: why selectedCustPosition is incorrect.

While running application: Getting error "Index 0 requested, with a size of 0"

I am getting “Index 0 requested, with a size of 0” while starting application on mobile/device.
I am making sure that cursor is not ‘Null’ when I am calling.
I found some similar issue and tired in my scenario but don’t work.
I have this code:
SQLiteDatabase db = mDbHelper.getReadableDatabase();
Cursor resultSet=db.rawQuery("select * from NoteTable", null);
String[] values = new String[resultSet.getCount()];
if (resultSet != null && resultSet.moveToNext());
{
do {
if (resultSet != null) {
values[i] = resultSet.getString(resultSet.getColumnIndex("noteTitle"));
i++;
}
}while (resultSet.moveToNext());
resultSet.close();
}
db.close();
return values;
I am getting following exception:
09-24 15:28:23.845 25800-25800/com.example.ashv.actionbar W/System.err﹕ java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ashv.actionbar/com.example.ashv.actionbar.MyActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
You should first move to first record of Cursor by using moveToFirst(), like
if (resultSet != null && resultSet.moveToFirst());
{
do {
if (resultSet != null) {
values[i] = resultSet.getString(resultSet.getColumnIndex("noteTitle"));
i++;
}
}while (resultSet.moveToNext());
resultSet.close();
}
There is no issue in code that I have mentioned above in question (of course after Manish correction).
I figured out that in my application, I am using 'App drawer'. 'App drawer' code is checking all contents to display in list and all those supposed to come from data base (i.e. using this code. Reading from database). This is giving me error "Index 0 requested, with a size of 0". This is referring for App drwaer values. I have removed app drawer part and this code works fine (i.e. my application didn't crash and no exception). I need to find solution for dynamic 'App drawer' (this will be different story).
I just mentioned this becasue if you are wondering whats wrong with your code. Then probably you need to look into other sections/module of your application.
You should call moveToNext method on the resultSet first
while(resultSet.moveToNext){
if(resultSet != null) {
values[i] = resultSet.getString(resultSet.getColumnIndex("noteTitle"));
}
}
resultSet.close()
for details on reading from sqlite database https://developer.android.com/training/data-storage/sqlite

Using limit () and offset () in QueryBuilder (ANDROID , ORMLITE)

#SuppressWarnings("deprecation")
public List<Picture> returnLimitedList(int offset, int end) {
List<Picture> pictureList = new ArrayList<Picture>();
int startRow = offset;
int maxRows = end;
try {
QueryBuilder<Picture, Integer> queryBuilder = dao.queryBuilder();
queryBuilder.offset(startRow).limit(maxRows);
pictureList = dao.query(queryBuilder.prepare());
} catch (SQLException e) {
e.printStackTrace();
}
return pictureList;
}
I have a table of Pictures in the database, and must return a limited list, 20 lines at a time.
But when I use ex: QueryBuilder.offset(11).limit(30);
I can not return the list limited to 20 lines.
The list only comes to me with the limit.
It's as if the offset remain always with value 0
ex: (0 - 30)
Is there any other way to return a limited list for initial index and end index?
Could anyone help me?
This question was asked two months ago, but I'll answer if anyone stumbled on the same problem as I did.
There's misunderstanding about what offset means in this case, here follows what SQLite Documentations says about it
If an expression has an OFFSET clause, then the first M rows are omitted from the result set returned by the SELECT statement and the next N rows are returned, where M and N are the values that the OFFSET and LIMIT clauses evaluate to, respectively.
Source
Based on your query, you'll return 30 lines starting at the #11 line.
So the correct way is:
queryBuilder.offset(startRow).limit(20);
With limit being the number of rows that will return, not the ending row.
pictureList = dao.query(queryBuilder.prepare());
And the returned List with the first value starting on pictureList.get(0)
Edit: #Gray 's help on comments

Android Cursor - moveToNext() doesnt seem to go to end of cursor

Why doesnt my Android Cursor go all the way to the end of the original "promise"??
My cursor.getCount() differs from my last cursor.getPosition(). Check my while loop! It is all I do with it!
Notes:
1. it is about querying the Contacts content provider (android api >5)
2. I display only the esential code
Cursor cursor = mContext.getContentResolver().query(mUri, mProjections, null, null, null);
Logger.d(TAG, "*** cursor.getCount(): "+cursor.getCount());
while (cursor.moveToNext()) {
Logger.d(TAG, "| position: "+cursor.getPosition());
processMainCursor(serializer, cursor);
}
cursor.close();
processMainCursor() will display data from cursor + do another queries: one 4 phones, one 4 emails, one 4 IM accounts:
void processMainCursor(XmlSerializer serializer, Cursor main_cursor) {
writeCursorData(serializer, main_cursor); //writes cursor data, column by column
writePhoneEntities(serializer, main_cursor);
writeEmailEntities(serializer, main_cursor);
writeIMEntities(serializer, main_cursor);
}
In none of my writeXXX methods do i close my main_cursor or move next!!!..have to trust me on that.. i just do a new query, print data & close that cursor
So statistics:
cursor.getCount() = 695 (always)
commenting writePhoneEntities, writeEmailEntities, writeIMEntities: cursor.getCount() =
last cursor.getPosition() = 695 (so correct!)
leaving one/two/all of my writeXEntities shows randomness; example: leaving them all:
last cursor.getPosition() sometimes displays 254, 257, 253, etc; leaving just phone & IM: 514, 510, 511, etc (so different RUN -> different last cursor.getPosition() VALUE)
So oppinions.. Why is that? Is it memory related?
Update:
Leaving any of my writeXEntities displays at the end in logcat:
Removing dead content provider: contacts
Update 2
Adding cursor.moveToFirst(); & doing loop like
do {
//do whatever you want
} while (cursor.moveToNext());
didn't do the job..
So maybe the answer is in this logcat entries:
05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: contacts
05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: com.android.contacts
SAMPLE OF a writeXEntity REMOVED
SOLUTION .. i wasnt closing the cursors from writeXEntity corectly (probably leaving quite a lot of open cursor after main while)
in reality i was closing like this
if(phone_cursor!=null && phone_cursor.getCount() > 0)
{
//... stuff
phone_cursor.close();
}
i should have closed after if
if(phone_cursor!=null && phone_cursor.getCount() > 0)
{
//... stuff
}
phone_cursor.close();
I guess leaving a basilion cursor open ..was the answer?!?
You need to move the cursor to the first row. Try adding cur.moveToFirst() before the while loop.
You might also consider using a do-while loop. This will ensure that you never skip over the first row in the cursor:
if (cursor.moveToFirst()) {
do {
//do whatever you want
} while (cursor.moveToNext());
}
cursor.close();
Well, they won't be the same number as the getCount is the number of items, and the position is the position, ( the first one being 0). So the final position should always be one less than the count.
If it's something other than that, I guess I'm not understanding your question properly.
Use cursor as shown below:
if(cursor.getCount() == 0)
{
//No entry found
}
else {
cursor.moveToFirst();
do {
//do whatever you want
} while (cursor.moveToNext());
cursor.close();
After reading the answer you already found (problem with closing cursors) I think that the best way to ensure you close them all is with this code:
Cursor c = null;
try {
c = <your query>;
if (c.moveToFirst()) { // No point in doing more if empty.
do {
<process this cursor row>
} while (c.moveToNext());
}
}
finally {
if (c != null) c.close(); // Not sure the check needed, maybe if query was really wrong.
}

Display all records that are stored in SQlite database

I want to display all my records that are stored in the database
c = db.DBhelper.getChamp1(c.getCount);
//startManagingCursor(c);
int j = 0;
stateNameArray = new String[c.getCount()];
c.moveToFirst();
while(!c.isAfterLast()) {
stateNameArray[j] = c.getString(0);
j++;
Log.i("DEBUG_SQL","" + c.getString(0)+ " "+c.getString(j));
c.moveToNext();
}
//String resultat = ;
Log.i("DEBUG_SQL","" + c.getColumnIndex("article"));
I get an error when I write c.getCount – why? When I write a number like 1 or 2 or 3... that works.
And if I write
c = db.rawQuery("SELECT * FROM loan", null);
I get an error, but if I write
db.rawQuery("SELECT * FROM loan WHERE _id=1", null);
That works. Why?
At the very least, I see a problem with this log statement, where c.getString(j) doesn't make sense. And it may trigger an error as j gets larger.
Log.i("DEBUG_SQL","" + c.getString(0)+ " "+c.getString(j));
What data did you intend to access with the statement c.getString(j)?
On the getCount error. I assumed the error in the following was a typo. But is this where the error associated with getCount was located?
c = db.DBhelper.getChamp1(c.getCount);
But I shouldn't assume - you never know. It should read (add brackets to the method call).
c = db.DBhelper.getChamp1(c.getCount());
And as #Barak mentioned, what is going on with this statement?
To answer the question about your getCount isuue, you get the error because of this:
c = db.DBhelper.getChamp1(c.getCount);
You're trying to get the count of the cursor before you have it (and you're missing ()).
This would work since you have a cursor to count before you pull the next one:
c = db.getSomeCursor;
c1 = db.DBhelper.getChamp1(c.getCount());
Let us know what you're trying to achieve (I can't figure it out from the code you posted) and maybe we can be more helpful.

Categories

Resources