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

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是什么意思?
根据我的理解,acontact是一组raw_contacts。例子:
电话簿中有2个:
[ 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|

据我所知:
contacts=用户A或用户B。
raw_contacts=用户A(电话)或用户A(SIM卡)或用户A(谷歌)或用户A(Viber)……
我的问题是:
如果我在acontacts中遍历所有contacts,然后在araw_contacts中遍历所有contact,请记住,原始联系人可能很多,然后遍历每个原始联系人的电话号码(家庭、移动电话、工作电话……),那么这对性能不是很不利吗?
我应该怎么做才能只循环通过手机(SIM卡或设备)上存储的手机号码,而不必循环通过自定义应用程序生成的raw_contacts
在所有raw_contacts之间循环是没有意义的。
像WhatsApp、Viber、Telegram或任何手机应用程序都能快速高效地获得这些联系人。
谢谢。

最佳答案

……那对表演不是不好吗?
绝对是糟糕的表现。
我该怎么做才能只循环浏览手机号码?
直接遍历ContactsContract.Data表,从所有rawcontacts获取所有电话。
像WhatsApp、Viber、Telegram或任何手机应用程序都可以获得这些
快速有效地联系。
这是部分错误的,因为这些应用程序运行一个服务来查询联系人、与服务器通信,然后在本地缓存结果,所以看起来非常快。然后他们只需要定期查询delta(添加/删除联系人)。即使使用下面更快的代码,也可以在后台线程中运行,因为根据设备上的联系人数量,运行此代码可能需要时间。
示例代码:

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!

08-25 23:17