【问题标题】:How to retrieve every possible contact?如何检索每个可能的联系人?
【发布时间】:2018-08-19 15:22:45
【问题描述】:

有多个示例说明我们如何在 android 中检索联系人,最常见的类型是使用 ContactsContract,如下所示:

ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.contacts.CONTENT_URI,null,null,null,null);

while(cursor.moveToNext){
//get contact details
.........

}

我的问题:

如果用户可以将他们的联系人保存在三个位置phoneSIMgoogle_account。那么我如何能够使用一种方法来检索用户在手机上的所有号码?

同样由于手机中的联系人列表重复联系人,我们如何避免获得联系人两次或四次或五次?

必须使用什么方法才能覆盖所有可能的联系人?

【问题讨论】:

    标签: android android-contacts contactscontract


    【解决方案1】:

    用户实际上可以在很多地方保存联系人,而不仅仅是 3 个,例如如果用户安装了Yahoo 应用程序,他们也可以开始在Yahoo 上存储联系人,Outlook 也是如此,等等。

    ContactsContract 涵盖所有这些选项,并提供单一 API 来查询存储在设备上的所有联系人。 不同的存储类型由ACCOUNT_NAMEACCOUNT_TYPERawContact 级别区分。

    您从查询中获得的Contact 结果实际上是来自一个或多个来源或ACCOUNT_TYPEs 的多个RawContacts 的聚合,因此请在您的SIM 和手机上复制RawContacts 应该聚合成一个Contact

    这里有一些代码可以在你的设备上探索你自己的联系人(这是非常慢的代码,有一些方法可以显着提高性能):

    String[] projection = new String[] { Contacts._ID, Contacts.DISPLAY_NAME};
    Cursor contacts = resolver.query(ContactsContract.Contacts.CONTENT_URI, projection, null, null, null);
    
    while (contacts.moveToNext()) {
    
        long contactId = contacts.getLong(0);
        String name = contacts.getString(1);
    
        Log.i("Contacts", "Contact " + contactId + " " + name + " - has the following raw-contacts:");
    
        String[] projection2 = new String[] { RawContacts._ID, RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME };
        Cursor raws = resolver.query(RawContacts.CONTENT_URI, null, RawContacts.CONTACT_ID, null, null);
    
        while (raws.moveToNext()) {
    
            long rawId = raws.getLong(0);
            String accountType = raws.getString(1);
            String accountName = raws.getString(2);
    
            Log.i("Contacts", "\t RawContact " + rawId + " from " + accountType + " / " + accountName);
        }
        raws.close();
    }
    contacts.close();
    

    【讨论】:

    • 感谢您的回答,请问:1)这是否意味着即使我的电话簿中有重复的联系人,我在使用光标阅读时也会查询1个联系人。 2) SIM 卡是否被视为一个帐户,换句话说,ContactContract 除了 phone、google、yahoo 之外,还会返回 SIM 中的联系人吗?
    • (1) 这就是它应该工作的方式,Android 尝试将它认为是重复的原始联系人聚合到一个联系人中,实际上这并不总是完美无缺的。 (2) 是的,它们将返回 ACCOUNT_TYPE vnd.sec.contact.sim(对于某些供应商可能略有不同)
    • 那么从您提供的所有帐户的所有联系人的答案中:google、sim、phone、yahoo、viber、whatsapp 将被返回?
    • 在您看来,如果我在服务器上有联系人,并且想使用上述方法循环访问我的联系人以检查服务器上的号码.....是否意味着我将循环访问与服务器检查的原始联系人一样多(这需要时间).....如果我的用户 A 有 4 个帐户,这是否意味着如果我想检查服务器上的用户 A,我必须遍历所有帐户还是有主帐号?
    • 您可以而且应该跳过一些帐户,例如 whatsapp、viber 等,而专注于 Google、Exchange、Yahoo 等“真实”联系人存储。您可以遍历同步适配器列表以获取合适的同步适配器列表,然后将您的查询限制为仅在该列表中具有 ACCOUNT_TYPE 的联系人。见:stackoverflow.com/a/47001090/819355
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多