Android ContactsContract class: 如何忽略非主ACCOUNT_TYPES?

Android ContactsContract class: How to ignore non-primary ACCOUNT_TYPES?

所以我现在知道我可以使用 ContactsContract class 列出 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是什么意思:

一个contact按照我的理解是一组raw_contacts。示例:

这些是 phone 书中的 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|

据我了解:

我的问题是:

如果我遍历所有 contacts 然后在 contact 中遍历所有 raw_contacts 请记住 raw_contacts 可能很多,然后循环遍历每个原始联系人的 phone 号码(家庭、手机、工作...)...那么这不会对性能造成影响吗?

我应该怎么做才能只循环访问存储在 phone(sim 或设备)上的手机号码,而不必循环访问自定义应用程序生成的 raw_contacts

遍历所有 raw_contacts.

毫无意义

whatsapp 或 viber 或 telegram 等应用程序或任何 phone 应用程序可以快速有效地获取这些联系人。

谢谢。

...Then wouldn't it be bad for performance?

绝对糟糕的表现。

What should I do to only loop through mobile numbers?

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

Apps like whatsapp or viber or telegram or any phone app get these contacts fast and efficiently.

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

示例代码:

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!