I'm creating an app which stores diary entries. Upon retrieving the diary entry I get a CursorIndexOutOfBoundsException, I believe it is something to do with my SELECT statement to get the information within the DB.
getDAO = new DAO(this);
Cursor showDiaryEntries = getDAO.queryDiary(Diary.DiaryItem.FULL_PROJECTION, Diary.DiaryItem.COLUMN_NAME_DIARY_TITLE+" = "+fieldTitle, null);
Long fieldDate = showDiaryEntries.getLong(1);
Long fieldTime = showDiaryEntries.getLong(2);
String fieldEntry = showDiaryEntries.getString(3);
mDate.setText(String.valueOf(fieldDate));
Log.i(TAG,"Field Date "+ fieldDate);
mTime.setText(String.valueOf(fieldTime));
Log.i(TAG,"Field Time "+ fieldTime);
mEntry.setText(fieldEntry);
Log.i(TAG,"Field Entry "+ fieldEntry);
I've been reading about this type of exception and believe it may be to do with when I getting the String/Long as I don't have a loop? Although I don't fully comprehend this.
Log Cat
03-07 07:10:59.475: E/AndroidRuntime(1471): FATAL EXCEPTION: main
03-07 07:10:59.475: E/AndroidRuntime(1471): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.democo.mydiary/com.democo.mydiary.DiaryEntryActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
I was hoping someone would be able to educate me as to what the problem is.
Thanks
Make sure you call:
showDiaryEntries.moveToFirst();
Do this before you start doing anything to the cursor. This will make sure the cursor starts at the FIRST row in the database!
first make sure your cursor is
*not null
*Then move it to first position
if(showDiaryEntries!=null && showDiaryEntries.moveToFirst())
{
//Now do waht ever u want to do with cursor
}
Above code will take care of problem you are facing now and also which you may face in future.
When you fill a cursor, it is positioned BEFORE the first record (which index is 0); now your cursor index is -1, which corresponds to no record position.
Therefore you get an error (You try to get the values from the columns of no row).
This s why you should always moveToFirst your cursor before starting to use it.
Following code is to used for how to get cursor value.
Cursor showDiaryEntries= dbh.database_function();
if (showDiaryEntries.getCount() != 0 && showDiaryEntries!=null) {
if (showDiaryEntries.moveToFirst()) {
do {
fieldEntry = showDiaryEntries.getString(showDiaryEntries.getColumnIndex("database feild name here"));
} while (showDiaryEntries.moveToNext());
}
}
i am providing string for an example. so update your function with your long and string field..
Related
Is there anyone who can try to find the mistake in my code? I tried many things already but it always ends up with the same error.
This is my code:
String signeedep = spn.getSelectedItem().toString();
int a = spn1.getSelectedItemPosition();
Cursor userid = db.getallsigneenumber();
userid.moveToPosition(a);
Toast.makeText(getApplicationContext(),
userid.getString(1) + "//this is where the error points out
was assigned to the " + signeedep + ".",Toast.LENGTH_SHORT).show();
userid.close();
/*
db.open();
db.insertAssignsignee(signeedep, userid.getString(0));
db.close();
*/
myMethod();
This is my error:
FATAL EXCEPTION: main
android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
First make sure your cursor is not null and it is having required number of element in it..
remember moveToPosition(1) returns the second row, since it's zero-indexed
Probably you should first convert this to a String, using
String userIdString = userid.toString;
if possible.
Then you can use userIdString.substring(1,2);
i am using SQLLITE In Android, i am getting this strange error at
long a1 = cursor.getLong(0);
i have checked Cursor for null, i am checking if cursor contains rows, i am moving the cursor on first row but still i am getting the below error
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
if ( cursor.getCount()>0)
{
if (cursor.moveToFirst()) {
do {
long a1 = cursor.getLong(0);
} while (cursor.moveToNext());
}
}
I found the solution, i was having a blob column in the row which was filled with very large image.
A long shot : if I recall correctly the column numbering in all JDBC features starts at ONE, not at ZERO.
so I've build a method that return an ArrayList of a class that I use on my project, the problem is that the only item that is being add to the ArrayList is the 2nd on the database. I know that because I extracted the DB File and browsed it, and also the 'c.getCount()' return a value of 2.
So I know for a fact that my DB includes 2 entries, my Cursor gets 2 entries... but for some reason he chooses to focus on the 2nd row at the beginning after I created it - and thus exiting the while loop, even thought I called c.moveToFirst();
Maybe I'm just tired and not seeng clearly what am I doing wrong... because I compared it to other methods in my code that works fine and I cannot tell the difference between them.
My method looks like this:
public ArrayList<Kiosk> getKiosks () {
ArrayList<Kiosk> kioskArrayList = new ArrayList<>();
db = dbHandler.getWritableDatabase();
String[] columns = {Tags.TAG_LOCAL_ID, Tags.TAG_ID_SERVER, Tags.TAG_NAME,
Tags.TAG_PHONE_NUMBER, Tags.TAG_CONTACT_NAME, Tags.TAG_SCHOOL_ID};
Cursor c = db.query(DatabaseHandler.TABLE_KIOSK, columns, null, null, null, null, null);
c.moveToFirst();
Log.i("tagg", "Size of the cursor is: " + c.getCount());
while (c.moveToNext()) {
Kiosk kiosk = new Kiosk();
kiosk.setLOCAL_ID(c.getInt(c.getColumnIndex(Tags.TAG_LOCAL_ID)));
kiosk.setIdServer(c.getInt(c.getColumnIndex(Tags.TAG_ID_SERVER)));
kiosk.setName(c.getString(c.getColumnIndex(Tags.TAG_NAME)));
kiosk.setPhoneNumber(c.getString(c.getColumnIndex(Tags.TAG_PHONE_NUMBER)));
kiosk.setContactName(c.getString(c.getColumnIndex(Tags.TAG_CONTACT_NAME)));
kiosk.setSchoolId(c.getInt(c.getColumnIndex(Tags.TAG_SCHOOL_ID)));
c.moveToNext();
kioskArrayList.add(kiosk);
Log.w("taggg", "Added this to the kiosk Array: " + kiosk.getName() +
"Local ID: " + kiosk.getLOCAL_ID());
}
Log.w("tagg", "getKioskhere, size of the array I sent is: " + kioskArrayList.size());
c.close();
db.close();
return kioskArrayList;
}
My log gives clearly says the cursor's size is 2 but the ArrayList is 1:
03-11 14:18:37.334: W/(18369): School id of the client is: 1
03-11 14:18:37.336: I/(18369): Size of the cursor is: 2
03-11 14:18:37.336: W/(18369): Added this to the kiosk Array: PitaKioskLocal ID: 2
03-11 14:18:37.336: W/(18369): getKioskhere, size of the array I sent is: 1
Any advice? thanks in advance
You first move to the first element:
c.moveToFirst();
Then you move to the second one, before you even processed the first one:
while (c.moveToNext()) {
Finally, you call
c.moveToNext();
within your while loop, which leads to ignoring every second entry.
Solution: remove the call within the loop, and process the first element before moving on to the second one. The easiest method would be to change while(){} to do{} while().
Set the sort order for the query. You also do a moveToNext() prior to any work.
Cursor c = db.query(DatabaseHandler.TABLE_KIOSK, columns, null, null, null, null, Tags.TAG_LOCAL_ID + " desc");
// stuff
do {
// Iterate over cursor
} while (c.moveToNext());
It looks like you are calling moveToNext() too many times.
You start at the first row with your call moveToFirst(). Then, as you enter your while loop, moveToNext() is called again. Thus, as you enter your loop you are already sitting on the second row. Then, inside the loop, you call moveToNext() and add your kiosk too the kioskArrayList.
When you hit the top of the while loop the second time, you are sitting at an index of 2, so c.moveToNext() evaluates to false, so you only add to the list once.
So I'm trying to do some simple research on my own into different types of columns in the cursors for an SMS app, but when trying to get the type of the columns, I continually get -1 as an index. I've even hard coded in column number 0 and it still reverts to -1 for some reasons. Any help would be greatly appreciated, I'm at a loss for words with what's going on.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String tempUri = "content://mms-sms/conversations";
Uri uri = Uri.parse(tempUri);
Cursor c = getContentResolver().query(uri, null, null, null, null);
items = new ArrayList<>();
int length = c.getColumnCount();
for (int i = 0; i < length; i++) {
Log.i(TAG, "" + i);
Items item = new Items();
Log.i(TAG, "" + i);
item.columnName = String.valueOf(c.getType(0));
Log.i(TAG, "" + i);
items.add(item);
}
setListAdapter(new Adapter(this, R.id.list_item, items));
}
The error occurs in the for loop when calling c.getType(). Right now it's hard coded and I still get the same error. I've copied the stack trace below:
01-28 17:40:03.050 29753-29753/com.bluhmann.testapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bluhmann.testapp, PID: 29753
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bluhmann.testapp/com.bluhmann.testapp.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 9
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2336)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2408)
at android.app.ActivityThread.access$900(ActivityThread.java:147)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5273)
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:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 9
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getType(AbstractWindowedCursor.java:130)
at android.database.CursorWrapper.getType(CursorWrapper.java:146)
at com.bluhmann.testapp.MainActivity.onCreate(MainActivity.java:45)
at android.app.Activity.performCreate(Activity.java:5940)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
P.S. Missing some bottom lines of the stack trace... It won't go into the code format, but it's the very end so I'm not sure how useful it will be. If it's needed I'll try and figure out how to get it into code.
P.P.S. Using getColumnName() works fine with the same code, and both are supposed to give back the result based on the zero based index, so I don't see why one method doesn't work and the other does.
You need to move the Cursor's index to a row that has data before you check data types. For example:
c.moveToFirst();
Though the column names will always be the same - which is why the getColumnName() method works as is - types are tied to individual values in SQLite, so types aren't available per column, but rather per value.
Well it's one year late but i think it doesn't hurt to try to explain this with a bit more detail.
A table uses two indices. The one you're setting to 0 is the column index. However you didn't set the row index as Mike M. explained before, thus it remained on -1.
If you want to iterate through all fields, i'd recommend a do{}while(); loop containing a for(item:list) loop like this:
String[] colNames = cursor.getColumnNames();
int colIndex;
int rowIndex;
if (cursor.moveToFirst()) { // sets the cursor position / row index to 0
do {
rowIndex = cursor.getPosition();
for ( String colName : colNames ) {
colIndex = cursor.getColumnIndex(colName);
Log.i(TAG,
"Column Name: " + colName +
"Current Row: " + Integer.toString(rowIndex) +
"\nType = " + Integer.toString(cursor.getType(colIndex)) /*+
"\nValue" + cursor.getString(index)
or cursor.getInt(index)
or cursor.getFloat(index)
or cursor.getLong(index)
etc.
You can compare the type from cursor.getType(index)
with the Cursor.FIELD_TYPE_* constants
*/);
}
} while (cursor.moveToNext());
}
This way you always have the name of the current column available plus the index of the current row, allowing you to identify the exact field you are looking at while debugging.
The methods moveToFirst() and moveToNext() return boolean values: true if the row exists, false if not.
The getColumnName(int) doesn't require the row index as merely contains the names of the columns, that's why you have no problem on that line when using the column index 0. As you see there is also a method to get all column names as array, used in the above example.
Sadly there does not seem to be a way to retrieve the types if no values are present. Correct me if i'm wrong here.
I have two buttons. One for previous and one for next sqlite database record.
Here is how i am trying to get the next record from the database.
public long getNext(int id,DataBaseHelper helper){
Story story = new Story();
Cursor cursor = story.getStories(helper, 0);
//Updated code
cursor.moveToPosition(id);
cursor.moveToNext();
return cursor.getLong(1);
//Updated code
}
The problem is that if the previous position i pass it is "1", the next position i get is "3". Why does it skip one record? It keeps on skipping one record every time. Please tell me if i'm doing something wrong since i'm new at this and i have looked everywhere but this specific issues seems to be happening to me.
UPDATE : Code edited to show a better approach(perhaps)
Remember that Cursor.getPosition() starts to count from 0. So, the first record is at index #0, the second one at index #1, ...
Take a look at the official documentation : Cursor.moveToPosition(int position)
Let take a look at your code :
(id = 1, for the example)
cursor.moveToPosition(id);
// Cursor is now on the record #1, so the second one of the list
cursor.moveToNext();
// Cursor is now on the record id+1 = #2, so the third one of the list
return cursor.getLong(1);
// Returns the value of the colon #1 of the third record
// of the list : so the record at the index #2
Ok. I have been a little wrong with the approach here. I was ignoring the fact that the cursor index starts from -1 and that the database index of my table starts from 1. So i had to subtract -1 from the id variable and it solved the problem :) Here is the code that worked for me.
public long getNext(int id,DataBaseHelper helper){
id = id - 1;
Story story = new Story();
Cursor cursor = story.getStories(helper, 0);
//Updated code
cursor.moveToPosition(id);
cursor.moveToNext();
return cursor.getLong(1);
//Updated code
}