所以我现在知道我可以使用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
是什么意思?根据我的理解,a
contact
是一组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)……
我的问题是:
如果我在a
contacts
中遍历所有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!