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

Posted

技术标签:

【中文标题】如何加入具有不同 CONTENT_ITEM_TYPE 但共享一个公共字段的记录,即 RAW_CONTACT_ID?【英文标题】:How can I join records with different CONTENT_ITEM_TYPE but that share a common field, namely 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

【问题讨论】:

【参考方案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。

以上是关于如何加入具有不同 CONTENT_ITEM_TYPE 但共享一个公共字段的记录,即 RAW_CONTACT_ID?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中将具有不同类型的项目列表作为字符串加入

加入具有不同结构的多个表?

熊猫加入具有不同名称的列[重复]

Pandas:在具有不同名称的字段上加入 DataFrames?

将一个维度加入具有不同粒度的多个事实表

从两个不同的来源加入同一张表