This question already has answers here:
How To Test If Cursor Is Empty in a SQLiteDatabase Query
(6 answers)
Closed 2 years ago.
When I'm trying to get the phone numbers from the contact list of the phone. The problem is, when I'm running the app while the contact list in the phone is empty, the app is stopped. I checked it and this is because the cursor is empty.
How can I check if the cursor is empty or if there are any contacts in the contact list of the phone?
ArrayList<String> lstPhoneNumber = new ArrayList<String>();
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
lstPhoneNumber = new ArrayList<String>();
phones.moveToFirst();
// The problematic Line:
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
while (phones.moveToNext()) {
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER)));
}
phones.close();
The general pattern to test for a "valid" cursor is
((cursor != null) && (cursor.getCount() > 0))
The Contacts Provider doesn't return null, but other content providers might do so if they encounter some sort of data error. A content provider should handle Exceptions, set the cursor to zero, and log the Exception, but there's no guarantee.
Use cursor.getCount() == 0. If true, the cursor is empty
I added in a projection so you are only getting the column you need.
String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
ArrayList<String> lstPhoneNumber = new ArrayList<String>();
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, null, null, null);
if (phones == null)
return; // can't do anything with a null cursor.
try {
while (phones.moveToNext()) {
lstPhoneNumber.add(phones.getString(0));
}
} finally {
phones.close();
}
public boolean isCursorEmpty(Cursor cursor){
return !cursor.moveToFirst() || cursor.getCount() == 0;
}
Try this one. The problem of your code is that it will execute add regardless of the length of the cursor. I enclose the phones.moveToFirst() in if statement since it will return false if cursor is empty or has no record set.
if(phones.moveToFirst()){
do{
lstPhoneNumber.add(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
}while(phones.moveToNext())
} else {
//do something else
}
System.out.println("count "+ cursor.getCount());
This will show value of cursor in logcat
cursor.moveToFirst();
if (cursor.isBeforeFirst()) //means empty result set
; //do your stuff when cursor is empty
isBeforeFirst() after a moveToFirst() works well also.
According to the Cursor documentation:
isBeforeFirst():
Returns whether the cursor is pointing to the position before the first row.
Related
I have an app that uses a cursor to run an SQlite query.
public Cursor totaltrips(){
Cursor cursor = database.rawQuery("SELECT * AS TTotal FROM " + DatabaseHelper.TABLE_NAME, null);
return cursor;
}
The results are stored to an Arraylist with a maximum of 5 values. If there are no records in the database the app crashes. If I have one or more database entries it works fine. Does anyone know how I can stop it from crashing when there are no database entries?
// get column value
if (Distance.moveToNext())
result = String.valueOf(Distance.getDouble(Distance.getColumnIndex("myTotal")));
tnmView.setText(result);
List<String> distancearray = new ArrayList<String>();
Cursor cursor = dbManager.totaldistance();
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));
ttrips = cursor.getCount();
Log.i("Graph", "TTRIPS = " + ttrips);
// Be sure here to have at least the 5 desired elements into the list
while(distancearray.size() < 5){
distancearray.add("0");
}
The app crashes with the error
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
On the line
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));
Check if cursor actually has results, try something like this for example:
int numResults = cursor.getCount();
if (numResults > 0) {
do {
distancearray.add(cursor.getString(1));
} while ((cursor.moveToNext()));
}
Replace
do{
distancearray.add(cursor.getString(1));
}while ((cursor.moveToNext()));
with
if (cursor != null) {
while (cursor.moveToNext()) {
distancearray.add(cursor.getString(1));
}
cursor.close();
}
Check if cursor is null and has more than one value.Close cursor after uses.
if(cursor!=null&&cursor.getCount()>0){
cursor.moveToFirst();
while(cursor.hasNext()){
//do stuff here
}
cursor.close();
}
How can I get every row from a content provider ? I tried to do this using Cursor c = getContentResolver().query(uri, null, null, null, null)
and then
String s;
if (c != null && c.moveToFirst())
while (c.moveToNext())
s = c.getString(c.getColumnIndexOrThrow("string"));
c.close();
but it didn't work.Instead of taking all the rows, it was taking only the last one, repeatedly, as many times as the rows-1 of my db.
You are getting "rows-1" because your use of moveToFirst() followed by moveToNext() as the loop control causes you to skip the first row.
If you are seeing all rows of the DB with the same value for column "string", there is either a problem with the code that shows you "s" (which you didn't post) or your DB contains the same value for every row, or you have not implemented query() correctly in your ContentProvider.
You can also use Cursor.getCount() to get the number of rows in the cursor.
This code works for me when run against a content provider backed by a DB:
Cursor c = getContentResolver().query(uri, null, null, null, null);
if (c != null) {
while (c.moveToNext()) {
String s = c.getString(c.getColumnIndexOrThrow("name"));
Log.i("Demo", s);
}
c.close();
}
My query return 198 registers but cursor only read one register.
Why?
The mCount property of Cursor show 198.
This code:
public ArrayList<EnderecoOficina> retornarListaEnderecoOficina(String sCampo,
String sWhere) {
ArrayList<EnderecoOficina> lista = new ArrayList<EnderecoOficina>();
String query = String.format("SELECT %s FROM %s WHERE %s",
sCampo,
MyDBConstants.TABLE_OFICINAS,
sWhere);
SQLiteDatabase db = dbHandler.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
int i = 0;
if (cursor != null && cursor.moveToFirst()){
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
} while (cursor.moveToNext());
cursor.close();
db.close();
return lista;
}
image link (my points not allow attach image here).
I think you're confusing while syntax.
while (cursor.moveToNext());
Will loop without doing anything until the Cursor is empty. I think you wanted a do/while as explained by CommonsWare answer.
In my opinion, this is an unnecessary complicated way to do it. A lot of people don't know how to use Android Cursor. I've seen all kinds of complicated ways to do it (checking for null, moving to first, moving to index...), but this is the simplest way:
try {
// Loop while there are records on the Cursor
while (cursor.moveToNext()) {
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
}
} finally {
// Make sure the cursor is closed no matter what
cursor.close();
}
There's no need to check for null, Android Cursor API never returns a null cursor. You also need to close the Cursor once you've finished with it.
Usually when I iterate over a cursor I use something like the following:
while (cursor.moveToNext()) {
// get stuff from the cursor
}
What's the best way to iterate an Android Cursor? has a nice discussion of the various options. But now I need to go backwards from last to first over the cursor.
So what can I do?
There are at least two options.
First, to specifically answer your question about iterating backwards over the cursor, you could do the following:
for (cursor.moveToLast(); !cursor.isBeforeFirst(); cursor.moveToPrevious()) {
// get stuff from the cursor
}
Second, you could populate the cursor in reverse order from sql and then iterate over the cursor in your normal way:
SQLiteDatabase db = myHelper.getWritableDatabase();
String[] columns = { MyDatabaseHelper.TEST_DATE, MyDatabaseHelper.SCORE };
String orderBy = MyDatabaseHelper.TEST_DATE + " DESC"; // This line reverses the order
Cursor cursor = db.query(MyDatabaseHelper.TESTS_TABLE_NAME, columns,
null, null, null, null, orderBy, null);
while (cursor.moveToNext()) {
// get stuff from the cursor
}
cursor.close();
db.close();
You can start the cursor in the last position, and use moveToPrevious() until you've finished.
cursor.moveToLast();
do
{
// Stuff
}
while (cursor.moveToPrevious());
The following statement cursor.moveToNext() is always false. I expect the loop to execute once. I've tested that the query actually returns data.
Does anyone know what is the matter?
String query ="SELECT(SELECT COUNT(*) FROM Table1) as count1, (SELECT COUNT(*) FROM Table2) as count2;";
Cursor mCursor = mDb.rawQuery(query, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
while (cursor.moveToNext()) { //<---------------return false here???
String result_0=cursor.getString(0);
}
I know you've solved your problem, but here is a walkthrough of what happened:
Cursor mCursor = mDb.rawQuery(query, null);
// At this point mCursor is positioned at just before the first record.
if (mCursor != null) {
mCursor.moveToFirst();
// mCursor is now pointing at the first (and only) record
}
while (mCursor.moveToNext()) {
String result_0=cursor.getString(0);
}
// The loop above was skipped because `.moveToNext()` caused mCursor
// to move past the last record.
So, in your case of only needing a single record, you only need either mCursor.moveToFirst() OR your mCursor.moveToNext().
you can iterate cursor this way.
if(moveCursor.moveToFirst()){
do{
//your code
}while(moveCursor.moveToNext());
}