【问题标题】:How can I join records with different CONTENT_ITEM_TYPE but that share a common field, namely RAW_CONTACT_ID?如何加入具有不同 CONTENT_ITEM_TYPE 但共享一个公共字段的记录,即 RAW_CONTACT_ID?
【发布时间】:2019-10-29 20:07:51
【问题描述】:

我需要Cursor 选择属于按姓氏排序的特定组的联系人(而不是 display_names)。

很容易得到一个光标返回属于所请求组的联系人,另一个返回按姓氏排序的联系人。 然而,姓氏属于ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE 的DATA 记录,而属于特定组的联系人可以在ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE 的记录中找到。

如何连接具有不同 CONTENT_ITEM_TYPE 但共享一个公共字段的记录,即RAW_CONTACT_ID

【问题讨论】:

    标签: android join android-contacts android-cursor


    【解决方案1】:

    您说您需要选择联系人,如果是这样,您不应该使用 RAW_CONTACT_ID,而是使用 CONTACT_ID 来加入您的联系人数据。 单个联系人可能是多个 RawContact 的聚合,在这种情况下,我假设您希望将单个联系人的所有详细信息放在一行中。

    现在要得到你想要的,你不能使用游标来遍历联系人,而是应该将你需要的所有数据加载到内存中(例如 HashMap)并运行。

    顺便说一句,如果您更喜欢查询 Contacts/RawContacts 表而不是 Data 表,您可以利用 DISPLAY_NAME_ALTERNATIVE 列进行排序,请参阅:https://developer.android.com/reference/android/provider/ContactsContract.ContactNameColumns.html#DISPLAY_NAME_ALTERNATIVE

    示例代码:

    int selectedGroupId = 12345;
    HashSet<Long> ids = new HashSet<>();
    
    // get all CONTACT_IDs belonging to some GROUP_ID
    String[] projection = new String[]{Data.CONTACT_ID};
    String selection = Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE + "' AND " + GroupMembership.GROUP_ROW_ID + "=" + selectedGroupId;
    Cursor c = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
    while (c.moveToNext()) {
        ids.add(c.getLong(0));
    }
    c.close();
    
    String[] projection = new String[]{Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1};
    // you can add more MIMETYPES to the selection here to get phones, emails, etc. for each contact
    String selection = Data.CONTACT_ID + " IN (" + TextUtils.join(",", ids) + ") AND " + Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'";
    c = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, StructuredName.FAMILY_NAME + " ASC");
    DatabaseUtils.dumpCursor(c);
    c.close();
    

    【讨论】:

    • 是的,使用 DISPLAY_NAME_ALTERNATIVE 解决了这个问题。非常感谢,Marmor。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 2020-07-26
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多