25

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();
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Yossi Zloof
  • 1,609
  • 3
  • 13
  • 13
  • Get rid of the phones.moveToFirst() and 1stPhonenumber.add calls.. leave your while loop. fixed. – dymmeh Feb 21 '13 at 19:42
  • Also, try passing in a projection of the columns you are querying for. No use retrieving all columns (by passing in null for the projection) when you only need 1. – dymmeh Feb 21 '13 at 19:45

7 Answers7

54

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.

LarsH
  • 27,481
  • 8
  • 94
  • 152
Joe Malin
  • 8,621
  • 1
  • 23
  • 18
25

Use cursor.getCount() == 0. If true, the cursor is empty

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
9

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();
}
dymmeh
  • 22,247
  • 5
  • 53
  • 60
5
public boolean isCursorEmpty(Cursor cursor){
   return !cursor.moveToFirst() || cursor.getCount() == 0;
}
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
Cao Manh Dat
  • 2,112
  • 1
  • 17
  • 15
4

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
   }
Ariel Magbanua
  • 3,083
  • 7
  • 37
  • 48
  • Or just do a while loop .. adding the extra if along with do/while looks ugly and adds pointless logic – dymmeh Feb 21 '13 at 19:43
2
System.out.println("count "+ cursor.getCount());

This will show value of cursor in logcat

Nick H
  • 8,897
  • 9
  • 41
  • 64
Abhay Pratap
  • 1,886
  • 11
  • 15
1
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.

Christopher J.
  • 1,154
  • 1
  • 12
  • 21