【问题标题】:How to retrieve all contacts details from Content provider with single query?如何通过单个查询从内容提供商检索所有联系人详细信息?
【发布时间】:2016-03-12 15:24:18
【问题描述】:

我需要从设备读取联系人。我需要的字段是IDDisplay NamePhone Number(所有类型)Email id(所有类型)和“照片”。为此,我现在正在这样做。

1 : 首先我正在读取来自ContactsContract.Contacts.CONTENT_URI; 的所有ids,如下所示

        Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;
        // Querying the table ContactsContract.Contacts to retrieve all the contacts
        String[] projection = {ID};
        Cursor contactsCursor = mContentResolver.query(contactsUri, projection, null, null,
                "upper(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC");

2 :然后遍历此光标以读取所有联系人的所需字段。

if (contactsCursor.moveToFirst()) {
            do {
                 long contactId = contactsCursor.getLong(contactsCursor.getColumnIndex(ID));
                   Uri dataUri = ContactsContract.Data.CONTENT_URI;
                // Querying the table ContactsContract.Data to retrieve individual items like
                // home phone, mobile phone, work email etc corresponding to each contact
                   String[] columns = {CONTACT_ID, PHOTO_URI, DISPLAY_NAME, MIME_TYPE, DATA_1, DATA_2, DATA_4};
                   String selection = ContactsContract.Data.CONTACT_ID + "=" + contactId;
                   Cursor dataCursor = mContentResolver.query(dataUri, columns,
                        selection,
                        null, null);
                                 if (dataCursor.moveToFirst()) {
                                 // Getting Display Name
                                 displayName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                                 do {
                                    // Getting Phone numbers
                                    String mimeType = dataCursor.getString(dataCursor.getColumnIndex(MIME_TYPE));
                                    switch (mimeType) {
                                             case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
                                             String phoneNumber = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
                                             switch (dataCursor.getInt(dataCursor.getColumnIndex(DATA_2))) {
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_HOME:
                                        homePhone = phoneNumber;
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
                                        mobilePhone = phoneNumber;
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_WORK:
                                        workPhone = phoneNumber;
                                        break;
                                    default:
                                        otherPhone = phoneNumber;
                                }
                                break;
                              // Getting emails
                              case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE:
                                switch (dataCursor.getInt(dataCursor.getColumnIndex(DATA_2))) {
                                    case ContactsContract.CommonDataKinds.Email.TYPE_HOME:
                                        homeEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
                                        break;
                                    case ContactsContract.CommonDataKinds.Email.TYPE_WORK:
                                        workEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
                                        break;
                                    default:
                                        otherEmail = dataCursor.getString(dataCursor.getColumnIndex(DATA_1));
                                }
                                break;
                               // getting photo Uri 
                               case ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE:
                                if (dataCursor.getString(dataCursor.getColumnIndex(PHOTO_URI)) != null) {
                                    photoUri = Uri.parse(dataCursor.getString(dataCursor.getColumnIndex(PHOTO_URI)));
                                }
                                break;
                        }

                    } while (dataCursor.moveToNext());


               } while (contactsCursor.moveToNext());

查询工作正常,但问题是迭代和获取每个联系人的详细信息需要花费太多时间。第一个查询快速返回,但整个延迟现在在第二部分,即遍历第一个查询的每一行并查询每个字段。这可以在单个连接查询中完成,以便优化性能吗?

【问题讨论】:

  • ContentProviderContentResolver 不支持 JOIN,部分原因是提供程序不需要由 SQL 数据库或任何其他理解“连接”是什么的东西支持。

标签: android android-contacts android-contentresolver contactscontract


【解决方案1】:

是的,您可以在单个查询中执行此操作 - 有关联系人的所有数据实际上都存储在单个表 Data 中,其中包含您需要的联系人的所有信息,包括 CONTACT_ID 和 DISPLAY_NAME,它们也托管在 @987654322 上@表。

因此,您需要在单个查询中从 Data 表中查询 所有内容,并使用从 CONTACT_ID 到某个联系人对象的 HashMap 将其分类为联系人(或者如果您更喜欢详细信息列表)。

(注意:确保仅从 ContactsContract 包中导入以下类)

Map<Long, List<String>> contacts = new HashMap<Long, List<String>>();

String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3, Data.PHOTO_ID};
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur != null && cur.moveToNext()) {
    long id = cur.getLong(0);
    String name = cur.getString(1);
    String mime = cur.getString(2); // email / phone / company
    String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
    int type = cur.getInt(4); // a numeric value representing type: e.g. home / office / personal
    String label = cur.getString(5); // a custom label in case type is "TYPE_CUSTOM"
    long photoId = cur.getLong(6);

    String kind = "unknown";
    String labelStr = "";

    switch (mime) {
        case Phone.CONTENT_ITEM_TYPE: 
            kind = "phone"; 
            labelStr = Phone.getTypeLabel(getResources(), type, label);
            break;
        case Email.CONTENT_ITEM_TYPE: 
            kind = "email";
            labelStr = Email.getTypeLabel(getResources(), type, label);
            break;
    }
    Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data + " (" + labelStr + ")");

    // add info to existing list if this contact-id was already found, or create a new list in case it's new
    List<String> infos;
    if (contacts.containsKey(id)) {
        infos = contacts.get(id);
    } else {
        infos = new ArrayList<String>();
        infos.add("name = " + name);
        infos.add("photo = " + photoId);
        contacts.put(id, infos);
    }
    infos.add(kind + " = " + data + " (" + labelStr + ")");
}

【讨论】:

    猜你喜欢
    • 2018-10-29
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多