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

Posted

技术标签:

【中文标题】在 Android 中使用 ContactsContract 检索电话号码 - 功能不起作用【英文标题】:Retrieving a phone number with ContactsContract in Android - function doesn't work 【发布时间】:2012-02-02 20:59:51 【问题描述】:

我编写了以下函数来检索属于 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 的原因吗?

【问题讨论】:

你确认你只有一个联系人吗? 是的,因为我在遍历第一个查询的结果光标时尝试获取每个联系人的电话号码。如果我有两个联系人,这也不适用于显示名称,不是吗? 您能否展示一下您是如何获得contactId 的,以便我自己尝试一下? 当然可以。我在上面的问题中添加了细节。感谢您的努力! 【参考方案1】:

要在第一部分获取联系人 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));

【讨论】:

不,请查看我在问题中的编辑。但是感谢到目前为止的回答:) @MarcoW。当您在问题中提供更多详细信息时,我现在已经更新了答案。这对我有用。 成功了,非常感谢!为什么 Contacts._ID 是错误的字段?那个领域有什么? 使用Contacts._ID,您实际上会得到Data._ID 列,因为两者都是"_id"。您想要的列是 "contact_id",因为您正在从 uri ContactsContract.Data.CONTENT_URI 提取数据。【参考方案2】:

因为您已将投影设置为 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));

希望这会有所帮助。

【讨论】:

感谢您的回答!您在示例中也将投影设置为空,不是吗?我认为当投影为空时,光标返回所有列。这是错的吗? 是的,你是对的。对不起,我错过了空值。我唯一可以建议的是检查contactID是否有效并通过该方法进行调试。也许先获取所有联系人,然后检查您是否有一个带有正在传递的联系人 ID 的联系人。 我确实检查了它是否有效。而且身份证似乎总是有效的。我只需要将 long 转换为 String。但请查看我在问题中的编辑,也许这会有所帮助。【参考方案3】:

您的 getContactPhone() 代码对我来说运行良好。我通过启动一个联系人选择器进行测试,选择一个联系人,然后使用返回的 ID 并将其传递给您的方法。

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

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

【讨论】:

感谢您的回答!没有空指针异常,managedQuery 只是找不到任何行。请查看问题中的完整代码:)

以上是关于在 Android 中使用 ContactsContract 检索电话号码 - 功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章

android中RawContacts.CONTENT_URI和ContactsContract.Contacts.CONTENT_URI的区别

何时在 Android 中使用 RxJava,何时使用 Android 架构组件中的 LiveData?

在 Android 12 中使用 WorkManager

如何在 android 应用程序中使用 OSM 地图。?有啥教程可以学习在android中使用OSM吗?

如何在Mac中使用Android SDK

在 Android 中使用 Intent 在活动中传递 android 位图数据