I have created a database and i want to retrieve some data from the database by using the cursor by i always get this error
04-19 20:02:56.747: E/AndroidRuntime(301): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
here is the code of the function
public double getlatitude(String[] i,int x) {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_SQUAREID, KEY_SQUARELATITUDE, KEY_SQUARENAME,
KEY_SQUARELONGITUDE
};
Cursor c;
c=ourDatabase.query("squares", columns,"squarename=?",i, null, null, null);
String latitude = null;
if (c.moveToFirst()) {
latitude=c.getString(0);
}
double latitude_double=Double.parseDouble(latitude);
return latitude_double;
}
Try this
if(c.getCount() > 0) {
c.moveToFirst();
for(int i=0;i<c.getCount();i++) {
//do your logic here
}
}
The exception likely occurred because your cursor is empty (there may have been no match). To avoid this make sure that you check whether the cursor is empty or not, if it is empty then you should not try to access it. And if it is not empty, you should check the max row count and make sure that you don’t access to any row that is equal or higher than the max row count. See the code below:
if ( c != null && c.getCount() > 0 ) {
if (c.moveToFirst()) {
do {
// do something here
} while (c.moveToNext());
}
c.close();
}
I think the problem is here:
latitude=c.getString(0);
Change it to:
latitude = c.getString(c.getColumnIndex("column_name"));
and also dont forget to close your cursor before returning value by calling c.close();
Whenever you are dealing with Cursors, ALWAYS check for null and check for moveToFirst() without fail, if you want to avoid weird crashes in the future.
if( c != null ){
if( c.moveToFirst() ){
//Do your stuff
}
}
//After finishing always close the cursor.
c.close();
Related
I'm using a cursor in a while loop to execute multiple queries on my database, so each time Content Resolver returns new cursor object instance. I am uncertain about proper way I should reuse the cursor during each iteration of the loop:
Close it once, after all operations being performed
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
}
} finally {
if (c != null) {
c.close()
}
}
Close it at the end of each iteration
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
if (c != null) {
c.close()
}
}
} finally {
if (c != null) {
c.close()
}
}
Create new cursor variable inside while loop
while(condition) {
Cursor c = Context.getContentResolver().query(...);
try {
// fetching values
} finally {
if (c != null) {
c.close()
}
}
}
?
Case 1 is bad since you're assigning a new cursor in your loop and you only get to close the last assigned cursor.
Case 2 and 3 are very similar but I prefer case 3 because with case 2 you can break out of your loop unexpectedly but with case 3 you keep the cursor in the loop scope and the loop can keep running.
In your examples the third variant is most useful because you open-close the same Cursor object in each loop. You lost nothing: niether memory leaks no app+db crashes.
I have a cursorLoader which returns a cursor with this data:
0 {
email=bogdan#gmail.com
about=Party
}
1 {
email=bogdan1#gmail.com
about=Paaarty
}
2 {
email=bogdan2#gmail.com
about=activity 2
}
3 {
email=bogdan3#gmail.com
about=activity 3
}
4 {
email=bogdan4#gmail.com
about=activity 5
}
How can I save the emails in an ArrayList called emails and the about in an ArrayList called about. I've been trying different things with the cursor but most of the time I just get outOfBounds.
Edit: This is the line that prints it like that:
Log.v("Cursor Object", DatabaseUtils.dumpCursorToString(cursor));
If you want to do it your way maybe this method would help (provided that you supply two empty ArrayList) ?
private void populateLists(Cursor cursor, List<String> emails,
List<String> about) throws IllegalArgumentException {
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
emails.add(cursor.getString(cursor
.getColumnIndexOrThrow("email")));
about.add(cursor.getString(cursor
.getColumnIndexOrThrow("about")));
} while (cursor.moveToNext());
}
}
i'm show the particular data into listview bt it doenot show anything even my emulator goes blank....
the query is as..
SQLiteDatabase sd = db.getReadableDatabase();
String select = "SELECT * FROM pending_dues_table WHERE _pending_dues_id ="+i;
cr = sd.rawQuery(select, null);
if (cr != null) {
//cr.moveToFirst();
int ii;
ii=cr.getColumnIndex("pending_dues_notice");
while (cr.moveToLast()){
namelist.add(cr.getString(ii));
//studentno.add(cursor.getString(1));
}
}
ArrayList<String>combimelist=new ArrayList<String>();
for(int j = 0; j<namelist.size();j++){
combimelist.add(namelist.get(j));
}
adapter = new ArrayAdapter<String>(StudentDues.this,R.layout.student_due, combimelist);
and locat show error as..
05-25 03:33:56.225: E/AndroidRuntime(5134): FATAL EXCEPTION: main
05-25 03:33:56.225: E/AndroidRuntime(5134): java.lang.OutOfMemoryError: [memory exhausted]
05-25 03:33:56.225: E/AndroidRuntime(5134): at dalvik.system.NativeStart.main(Native Method)
Your logcat says
CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
......
at com.example.mytryapp.TeacherStudent$1.onClick(TeacherStudent.java:57)
so i think your problem is hare
if (get_rollno.equals(CR.getString(0)))
{
loginstatus = true; NAME=CR.getString(0);
}
and my suggestion is just check before call it that you must have some data.
try to do this Hope it works
if(cursor.getCount() > 0){
// get values from cursor here
if (get_rollno.equals(CR.getString(0)))
{
loginstatus = true; NAME=CR.getString(0);
}
}
or there is better way
try
Cursor cursor = //query here
while (cursor.moveToNext()) {
// retrieve values from the cursor
}
if there is any problem ... comment it
I have 5 empty TextViews where I add the names. After adding a name, it is stored in a database. The database consist on 2 columns, the item ID and the item NAME. This is an example of what I'm doing:
- Mark1 //ID=1, NAME= Mark1
- Mark2 //ID=2, NAME= Mark2
- Mark3 //ID=3, NAME= Mark3
- Empty
- Empty
I add and edit perfectly the textViews, but I'm facing a problem when deleting. This has something to do with the way I'm getting the values from the database, I'll explain:
Every time the app starts, or I edit, add or delete one element, what I do is get the items from the database, get them into a Map, and copy them into the textviews (whose at a first time are invisible) making visible just the ones that have a name setted.
This is the code I use to do that:
public void getTravelers() {
/*Create map where store items*/
Map<Integer, String> nameList = new HashMap<Integer, String>();
/*Lon in providers query() method to get database's items and save them into the map*/
Cursor c = getContentResolver().query(TravelersProvider.CONTENT_URI, PROJECTION, null, null, null);
if (c.moveToFirst()) {
do {
nameList.put(Integer.parseInt(c.getString(c.getColumnIndex(Travelers._ID))), c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
/*Check size*/
int size = nameList.size();
if (size >= 1) {
/*Save items in TextViews*/
//TODO: This is the code I should fix
for (int i = 0; i <= size; i++) {
if (i==1) {
traveler1.setText(nameList.get(i).toString());
traveler1.setVisibility(View.VISIBLE);
}
if (i==2) {
traveler2.setText(nameList.get(i).toString());
traveler2.setVisibility(View.VISIBLE);
}
if (i==3) {
traveler3.setText(nameList.get(i).toString());
traveler3.setVisibility(View.VISIBLE);
}
if (i==4) {
traveler4.setText(nameList.get(i).toString());
traveler4.setVisibility(View.VISIBLE);
}
if (i==5) {
traveler5.setText(nameList.get(i).toString());
traveler5.setVisibility(View.VISIBLE);
}
}
}
}
The problem comes in the for loop. Let's supposse that from the items named above, I want to delete Mark2 with ID=2, so then the size of the new Map would be 2, and it would enter to (i == 1) and (i == 2). But when entering to this last one, it would do traveler2.setText(nameList.get(2).toString()); and as seen, there is no element existing with the ID=2 because that is the one that I've deleted and it throws a NPE.
So my question is, what would be the right way to do this without facing this problem?
You should go for switch case other than for loop. Than code will not be in loop.
Finally I get what I need just changing the Key value of the Map that was the same as the ID of the database:
if (c.moveToFirst()) {
int key = 0;
do {
key++;
nameList.put(key, c.getString(c.getColumnIndex(Travelers.NAME)));
}while(c.moveToNext());
}
if (c != null && !c.isClosed()) {
c.close();
}
Basically this way I don't need to change nothing more as now the key value of the Map will match with the Textview position
I'm getting this error.
09-05 16:17:27.460: E/CursorWindow(29553): Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 8 columns.
09-05 16:17:27.465: E/AndroidRuntime(29553): FATAL EXCEPTION: main
09-05 16:17:27.465: E/AndroidRuntime(29553): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nesv.landstar/com.nesv.landstar.LandstarPage}: 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 don't know what I'm doing wrong with my code. Here it is:
Cursor c = null;
try
{
c = landstarDB.rawQuery("SELECT * FROM DriverShipment", null);
}catch (Exception e) {
Log.w("Error selecting table", "Error selecting table");
}
if (c != null && c.moveToFirst()) {
c.moveToFirst();
do {
Log.i("cctid:", c.getString(c.getColumnIndex("cctid")));
if(c.getString(c.getColumnIndex("cctid")) == cctid)
{
isRecorded = true;
shipmentId = c.getString(c.getColumnIndex("cctid"));
origin = c.getString(c.getColumnIndex("origin"));
destination = c.getString(c.getColumnIndex("destination"));
protectTime = c.getString(c.getColumnIndex("protect_time"));
readyTime = c.getString(c.getColumnIndex("ready_time"));
etat = c.getString(c.getColumnIndex("eta"));
if(c.getString(c.getColumnIndex("isAccepted")) == "1")
{
isAccepted = true;
}
}
}while(c.moveToNext());
}
c.close();
Any ideas? Thanks!
column -1 tells you that there is no column cctid, and getColumnIndex returns -1.
Also
c.getString(c.getColumnIndex("cctid")) == cctid
Will not work. Strings are compared using the equals method.
I suggest you post your table creation Query so we can see why the column is not there.
You have call c.moveToFirst(); two times
if (c != null && c.moveToFirst()) {
c.moveToFirst(); // Remove this one
Change your loop as below:
if (c.getCount > 0) {
c.moveToFirst();
do {
Log.i("cctid:", c.getString(c.getColumnIndex("cctid")));
if(c.getString(c.getColumnIndex("cctid")) == cctid)
{
isRecorded = true;
shipmentId = c.getString(c.getColumnIndex("cctid"));
origin = c.getString(c.getColumnIndex("origin"));
destination = c.getString(c.getColumnIndex("destination"));
protectTime = c.getString(c.getColumnIndex("protect_time"));
readyTime = c.getString(c.getColumnIndex("ready_time"));
etat = c.getString(c.getColumnIndex("eta"));
if(c.getString(c.getColumnIndex("isAccepted")) == "1")
{
isAccepted = true;
}
}
}while(c.moveToNext());
}