在安卓系统中从URI中获取联系人电话号码

9

我尝试在从内置活动中检索到联系人的ID号码后获取其电话号码。然而,无论我使用下面代码中的游标查询数据库时,都会返回零行,即使我选择的联系人有一个手机号码。

有人能指点我一个更好的方向或展示如何在获取用户ID后获取联系人的电话号码的示例吗?

我的代码:

    private Runnable getSMSRunnable() {
    return new Runnable() {
    public void run() {
    Intent i = new Intent(Intent.ACTION_PICK,
      ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
    startActivityForResult(i, CONTACTS_REQUEST_CODE);
   }
  };
 }

返回日志输出。
content://com.android.contacts/data/6802

我需要将ID(6802)传递给一个方法。该方法旨在通过给定类型(在本例中为ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)从ID返回电话号码。

public static String getContactPhoneNumberByPhoneType(Context context, long contactId, int type) {
    String phoneNumber = null;

    String[] whereArgs = new String[] { String.valueOf(contactId), String.valueOf(type) };

    Log.d(TAG, String.valueOf(contactId));

    Cursor cursor = context.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? and "
                    + ContactsContract.CommonDataKinds.Phone.TYPE + " = ?", whereArgs, null);

    int phoneNumberIndex = cursor
            .getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER);

    Log.d(TAG, String.valueOf(cursor.getCount()));

    if (cursor != null) {
        Log.v(TAG, "Cursor Not null");
        try {
            if (cursor.moveToNext()) {
                Log.v(TAG, "Moved to first");
                Log.v(TAG, "Cursor Moved to first and checking");
                phoneNumber = cursor.getString(phoneNumberIndex);
            }
        } finally {
            Log.v(TAG, "In finally");
            cursor.close();
        }
    }

    Log.v(TAG, "Returning phone number");
    return phoneNumber;
}

这个查询返回了电话号码的空值,也就是说它找不到我想要访问的行,说明我的查询出现了问题。但如果我检查一个有手机号码的联系人,怎么可能会出现0行的查询结果呢?

非常感谢您的帮助!

2个回答

12

我找到了答案。

我没有从游标中获取到任何行的原因是因为我使用了以下代码:

ContactsContract.CommonDataKinds.Phone.CONTACT_ID

“此数据所属的联系人表中的行id。”

由于我已经从联系人表中获取了URI - 这不是必需的,应替换为以下内容。ID应该对应于电话表中的联系人而不是原始联系人。

ContactsContract.CommonDataKinds.Phone._ID

交换返回的行在查询中产生了正确的结果。目前一切似乎都很顺利。


即使您的解释不清楚,这也是有效的。为什么Phone.CONTACT_ID(contact_id)与CONTACTS._ID(_id)不匹配? - redochka
也许这样解释更容易理解:_ID 是针对数据库的,而 CONTACT_ID 是用于在不查询特定表时的联系人 ID。这有帮助吗? - hwrdprkns
2
底线:Phones._ID == Contacts._ID - redochka

2

这应该可以工作,(也许尝试不使用type属性)

电话号码存储在它们自己的表中,需要单独查询。要查询电话号码表,请使用存储在SDK变量ContactsContract.CommonDataKinds.Phone.CONTENT_URI中的URI。使用WHERE条件语句来获取指定联系人的电话号码。

        if (Integer.parseInt(cur.getString(
               cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            Cursor pCur = cr.query(
        ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
        null, 
        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", 
        new String[]{id}, null);
        while (pCur.moveToNext()) {
        // Do something with phones
        } 
        pCur.close();
    }

对 Android 联系人 SQLite 数据库进行第二个查询,电话号码将根据存储在 ContactsContract.CommonDataKinds.Phone.CONTENT_URI 中的 URI 进行查询。联系人 ID 存储在电话表中的 ContactsContract.CommonDataKinds.Phone.CONTACT_ID 中,并使用 WHERE 子句来限制返回的数据。


1
你复制了你在同类型的另一个问题(http://bit.ly/ayUbeg)上的答案。我看了那个问题,但我不应该因为我的初衷而这样做。 - hwrdprkns

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