【问题标题】:Android ContactsContract class: How to ignore non-primary ACCOUNT_TYPES?Android ContactsContract 类:如何忽略非主要 ACCOUNT_TYPES?
【发布时间】:2018-08-21 18:12:03
【问题描述】:

所以我现在知道我可以使用ContactsContract 类来列出安卓设备上所有可用的联系人。像这样的:

private void getContacts(){

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

while(cursor.moveToNext){

//get contact id
.....
//get contact name
....

}

}

上面contact是什么意思:

一个contact根据我的理解是一组raw_contacts。示例:

这些是电话簿中的 2 个contacts

[ User A  ]
----------- 
[ User B  ]

点击用户A后,我会得到这个:

   | User A                                             |
   | phone 1: 0000 mobile                               | 
   | phone 2: 1111 home                                 |
   | phone 3: 2222 work                                 |
   |                                                    |
   |        linked :google , sim, phone, viber, whatsapp|

据我了解:

  • 联系人 = 用户 A 或用户 B。

  • raw_contacts = 用户 A(电话)或用户 A (SIM) 或用户 A (google) 或用户 A (viber)....

我的问题是:

如果我遍历所有contacts,然后在contact 中遍历所有raw_contacts 记住raw_contacts 可能很多,然后遍历电话号码(家庭、手机, work...) 的每个原始接触...那不会对性能不利吗?

我应该怎么做才能只遍历手机(SIM 卡或设备)上存储的手机号码,而不必遍历自定义应用生成的 raw_contacts

循环遍历所有raw_contacts是没有意义的。

whatsapp、viber 或 telegram 等应用或任何电话应用都可以快速有效地获取这些联系人。

谢谢。

【问题讨论】:

    标签: android android-contacts contactscontract


    【解决方案1】:

    ...那岂不是对性能不好?

    性能肯定很差。

    我应该怎么做才能只循环手机号码?

    直接遍历ContactsContract.Data 表,以从所有 RawContacts 中获取所有电话。

    whatsapp、viber 或 telegram 等应用程序或任何电话应用程序都可以获得这些 快速有效地联系。

    这部分是错误的,它似乎超级快,因为这些应用程序运行一个服务来查询联系人,与服务器通信,然后在本地缓存结果。然后他们只需要定期查询增量(添加/删除的联系人)。即使使用下面更快的代码,也要在后台线程中运行它,因为它可能需要一些时间来运行,具体取决于设备上的联系人数量。

    示例代码:

    private class ContactInfo {
        public long id;
        public String name;
        Set<String> phones = new HashSet<>();
    
        public ContactInfo(long id, String name) {
            this.id = id;
            this.name = name;
        }
    }
    
    Map<Long, ContactInfo> contacts = new HashMap<Long, ContactInfo>();
    
    String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.DATA1};
    
    // limit data results to just phone numbers.
    // Note: you can potentially restrict the query to just phone & SIM contacts,
    // but that would actually make the query slower not faster, because you'll need multiple queries over the DB, 
    // instead of just a big one.
    String selection = Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'";
    
    Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);
    
    while (cur.moveToNext()) {
        long id = cur.getLong(0);
        String name = cur.getString(1);
        String data = cur.getString(2); // the actual info, e.g. +1-212-555-1234
    
        Log.d(TAG, "got " + id + ", " + name + ", " + data;
    
        // add found phone to existing ContactInfo, or create a new ContactInfo object
        ContactInfo info;
        if (contacts.containsKey(id)) {
            info = contacts.get(id);
        } else {
            info = new ContactInfo(id, name);
            contacts.put(id, info);
        }
        info.phones.add(data);
    }
    cur.close();
    
    // you now have a mapping between contact-id to an info object containing id, name, and a list of phone-numbers!
    

    【讨论】:

    • 谢谢,我真的很感激,问题:循环数据时,我是否会通过(SIM、电话、设备、谷歌、.. .)?联系人 ID 是唯一的吗?另外,当我得到一组数字时,会有重复的数字吗?
    • (1) 因为我将Map 用于contacts,所以密钥(联系人ID)将是唯一的(2)因为我使用Set 用于phones这些数字也将是唯一的,但可能会有不同格式的重复,例如“+1-212-5555”和“212-5555”。您可以通过将所有手机转换为 e164 格式,然后将它们添加到 phones 来避免这些问题
    • 所以我们有一个带有一组电话的contact_id,现在在检查我的服务器时,我必须检查服务器上是否有号码,以防我在服务器中检查号码并添加他们到本地缓存我将添加 2 甚至 3 个号码给同一个联系人?
    • 示例:在 whatsapp 中,如果一个联系人有多个号码(手机、家庭等)并且所有这些号码都存在于 whatsapp 服务器中,那么 whatsapp 将在您的联系人中将它们显示为同一个联系人,但他们将在数字旁边添加 Moblie、Home 或 Work.......但是如果这些数字是相同的数字,则意味着重复的 whatsapp 将忽略它们.......但是无论如何,whatsapp 是如何在本地推送数字的数据库,如果它们引用相同的唯一联系人 ID .....为什么 HOME、WORK、MOBILE 在 whatsapp 中引用相同的联系人 ID 时不会被覆盖?
    • 我认为您正在扩展您的原始问题,所有这些问题都是特定于实现的,您可以存储本地缓存,或者根据需要将内容发送到您的服务器,您可以为每个联系人存储多个号码如果需要,并且可以删除重复项,只需选择正确的集合和数据库解决方案
    猜你喜欢
    • 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
    相关资源
    最近更新 更多