在 Android 中使用 ContactsContract 检索电话号码 - 功能不起作用

发布于 2024-12-25 02:29:15 字数 2162 浏览 2 评论 0原文

我编写了以下函数,以便检索属于 ID 为“contactID”的联系人的一个电话号码。

检索电话号码的函数:

private String getContactPhone(String contactID) {
    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String[] projection = null;
    String where = ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?";
    String[] selectionArgs = new String[] { contactID };
    String sortOrder = null;
    Cursor result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
    if (result.moveToFirst()) {
        String phone = result.getString(result.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        if (phone == null) {
            result.close();
            return null;
        }
        result.close();
        return phone;
    }
    result.close();
    return null;
}

如何调用该函数:

ArrayList<Contact> resultContacts = new ArrayList<Contact>();
Cursor result = null;
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Event.CONTACT_ID,
        ContactsContract.CommonDataKinds.Event.START_DATE,
};
String where = ContactsContract.Data.MIMETYPE+" = ? AND "+ContactsContract.CommonDataKinds.Event.TYPE+" = "+ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[] {ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE};
String sortOrder = null;
result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
while (result.moveToNext()) {
    Long id = result.getLong(result.getColumnIndex(ContactsContract.Contacts._ID));
    String phone = getContactPhone(String.valueOf(id));
    ...
}
...

不幸的是,它不起作用。如果我使用从“ContactsContract.Contacts._ID”获得的值调用此函数,我会得到 null。为什么会这样呢?怎么了?

编辑:我曾经将 Contacts._ID 映射到 CommonDataKinds.Phone.CONTACT_ID - 但这不起作用。但现在我将 Contacts.DISPLAY_NAME 映射到 CommonDataKinds.Phone.DISPLAY_NAME 并且它突然起作用了 - 很奇怪,不是吗?但我宁愿映射 ID 而不是显示名称。所以这个问题仍然是热门话题。这可能是由于这些表中的 ID 不同造成的吗?这不是有查找ID的原因吗?

I wrote the following function in order to retrieve one single phone number that belongs to the contact with id "contactID".

The function which is to retrieve the phone number:

private String getContactPhone(String contactID) {
    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String[] projection = null;
    String where = ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?";
    String[] selectionArgs = new String[] { contactID };
    String sortOrder = null;
    Cursor result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
    if (result.moveToFirst()) {
        String phone = result.getString(result.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        if (phone == null) {
            result.close();
            return null;
        }
        result.close();
        return phone;
    }
    result.close();
    return null;
}

How this function is called:

ArrayList<Contact> resultContacts = new ArrayList<Contact>();
Cursor result = null;
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[] {
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Event.CONTACT_ID,
        ContactsContract.CommonDataKinds.Event.START_DATE,
};
String where = ContactsContract.Data.MIMETYPE+" = ? AND "+ContactsContract.CommonDataKinds.Event.TYPE+" = "+ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[] {ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE};
String sortOrder = null;
result = managedQuery(uri, projection, where, selectionArgs, sortOrder);
while (result.moveToNext()) {
    Long id = result.getLong(result.getColumnIndex(ContactsContract.Contacts._ID));
    String phone = getContactPhone(String.valueOf(id));
    ...
}
...

Unfortunately, it doesn't work. I get null if I call this function with the value that I got from "ContactsContract.Contacts._ID". Why is this so? What is wrong?

Edit: I used to map Contacts._ID to CommonDataKinds.Phone.CONTACT_ID - which didn't work. But now I map Contacts.DISPLAY_NAME to CommonDataKinds.Phone.DISPLAY_NAME and it works suddenly - strange, isn't it? But I would rather like to map the IDs instead of the display names. So the question is still topical. Could this be due to different IDs in those tables? Isn't this why there are lookup IDs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

提笔书几行 2025-01-01 02:29:15

要获取第一部分中的联系人 ID,您应该使用:

ContactsContract.Data.CONTACT_ID

而不是:

ContactsContract.Contacts._ID

因此投影应该是:

String[] projection = new String[] {
         ContactsContract.Data.CONTACT_ID,
         ContactsContract.CommonDataKinds.Event.CONTACT_ID,
         ContactsContract.CommonDataKinds.Event.START_DATE,
 };

然后当然会获取正确的行:

Long id = result.getLong(result.getColumnIndex(ContactsContract.Data.CONTACT_ID));

To get the contact id in the first part, you should use:

ContactsContract.Data.CONTACT_ID

instead of:

ContactsContract.Contacts._ID

So the projection should be:

String[] projection = new String[] {
         ContactsContract.Data.CONTACT_ID,
         ContactsContract.CommonDataKinds.Event.CONTACT_ID,
         ContactsContract.CommonDataKinds.Event.START_DATE,
 };

And then of course get the correct row:

Long id = result.getLong(result.getColumnIndex(ContactsContract.Data.CONTACT_ID));
指尖凝香 2025-01-01 02:29:15

您将得到 null,因为您已将投影设置为 null。投影基本上是您想要返回的列的列表,例如

String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};

通常,当您找到联系人时,他们可能有一个电话号码列表,因此您必须使用另一个光标来迭代电话号码,例如

Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);    
while (phones.moveToNext()) 
{    
     phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
}

希望这有帮助。

You are getting null because you have set your projection to null. The projection is basically the list of columns that you want returned e.g.

String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};

Usually, when you find the contact, they may have a list of phone numbers, so you have to use another cursor to iterate through the phone numbers, e.g.

Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);    
while (phones.moveToNext()) 
{    
     phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
}

Hope this helps.

勿忘初心 2025-01-01 02:29:15

您的 getContactPhone() 代码对我来说效果很好。我通过启动联系人选择器、选择联系人、然后使用返回的 ID 并将其传递到您的方法中进行测试。

所以我怀疑你确实传递了一个无效的ID。您可以发布空指针异常的完整堆栈跟踪吗?

是的,查找键可用,因为 _ID 不能保证保持不变,因为同步和联系人聚合会更改它们。

Your code for getContactPhone() works fine on my end. I tested by launching a contact picker, selecting a contact, then using the ID that was returned and passed that into your method.

So I suspect you are indeed passing in an invalid ID. Can you post the full stack trace for the null pointer exception?

Yes, lookup keys are available because _IDs are not guaranteed to stay the same since syncs and contact aggregation changes them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文