如何检查光标是否为空?

25
当我尝试从手机的联系人列表中获取电话号码时,遇到了问题。问题是,当我在手机的联系人列表为空时运行应用程序,应用程序会停止运行。我检查了一下,发现这是因为光标为空造成的。
我该如何检查光标是否为空或者手机的联系人列表中是否有任何联系人呢?
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();

去掉 phones.moveToFirst() 和 1stPhonenumber.add 的调用...保留 while 循环。问题已解决。 - dymmeh
此外,尝试传递你正在查询的列的投影。当你只需要一个列时,没有必要检索所有列(通过传递null作为投影)。 - dymmeh
7个回答

54
一般检测“有效”光标的模式如下:
((cursor != null) && (cursor.getCount() > 0))

联系人提供程序不会返回null,但其他内容提供程序可能会在遇到某种数据错误时返回null。内容提供程序应该处理异常,将游标设置为零,并记录异常,但没有保证。

25
使用 cursor.getCount() == 0。如果为真,则表示游标为空。

9
我添加了一个投影,这样你只会得到你需要的列。
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();
}

这是字母 L :) - Yossi Zloof
我认为手机光标不需要关闭功能。 - S.M_Emamian

5
public boolean isCursorEmpty(Cursor cursor){
   return !cursor.moveToFirst() || cursor.getCount() == 0;
}

4

试试这个。你代码的问题是无论游标长度如何,它都会执行 add 操作。我把 phones.moveToFirst() 放在 if 语句中,因为如果游标为空或没有记录集,则其返回 false。

  if(phones.moveToFirst()){
       do{
          lstPhoneNumber.add(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); 
        }while(phones.moveToNext())
   } else {
        //do something else
   }

或者只需使用 while 循环... 添加额外的 if 与 do/while 一起看起来很丑,并且增加了无意义的逻辑。 - dymmeh

2
System.out.println("count "+ cursor.getCount());

这将在 logcat 中显示游标的值。


1
cursor.moveToFirst();
if (cursor.isBeforeFirst()) //means empty result set
        ; //do your stuff when cursor is empty

isBeforeFirst()moveToFirst()后也能正常工作。

根据游标文档

isBeforeFirst(): 返回游标是否指向第一行之前的位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接