I need a Cursor
selecting contacts belonging to specific groups ordered by their family names (not display_names).
It is easy to get a cursor returning the contacts belonging to the requested groups, and another one returning the contacts sorted by family names.
However the family name belongs to DATA records with ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
while contacts belonging to specific groups are to be found in records with ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE
.
How can I join records with different CONTENT_ITEM_TYPE but that share a common field, namely RAW_CONTACT_ID
?
You said you need to select contacts, if so you shouldn't use RAW_CONTACT_ID, but instead CONTACT_ID to join your contacts data. A single Contact may be an aggregate of multiple RawContacts and in that case I assume you want all the details of that single contacts as one row.
Now to get what you want, you can't use a Cursor to iterate through the contacts, instead you should load all the data you need to memory (e.g. HashMap) and run through that.
BTW, if you prefer to query over the Contacts/RawContacts tables instead of the Data table, you can utilise DISPLAY_NAME_ALTERNATIVE column to get your sort, see: https://developer.android.com/reference/android/provider/ContactsContract.ContactNameColumns.html#DISPLAY_NAME_ALTERNATIVE
Example code:
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();