为联系人保存数据添加一个新的

Save data for contacts adds a new one

我正在开发一个应用程序,我需要在其中存储与联系人相关的数据。

我使用游标在recycleView中列出联系人,每个itemView都有一个星形按钮来将联系人设置为收藏(与系统不同)。

我设法将数据存储在 ContactsContract.Data 中,这样做:

private void addContactData(long contactId, String displayName, boolean favorite) {

    // displayName same as the value for Contacts.DISPLAY_NAME_PRIMARY

    ArrayList<ContentProviderOperation> ops =
            new ArrayList<>();

    ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, CUSTOM_ACCOUNT_TYPE)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, CUSTOM_ACCOUNT_NAME)
            .withValue(ContactsContract.RawContacts.CONTACT_ID, contactId)
            .build());

    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
            .build());

    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, CustomData.CONTENT_ITEM_TYPE)
            .withValue(CustomData.IS_FAVORITE, favorite)
            .build());

    try {
        ContentProviderResult[] contentProviderResults = cr.applyBatch(ContactsContract.AUTHORITY, ops);
        return contactUri;
    } catch (RemoteException | OperationApplicationException e) {
        Log.e(getClass().getSimpleName(), e.getMessage(), e);
        return null;
    }
}

我遇到的问题是两个联系人的名字 ej 完全相同。 "Tom" 和 "Tom" 如果我按下收藏按钮,则会添加第三个联系人,甚至会在设备联系人应用程序中列出。

一些搜索引导我添加更多数据来区分联系人使用:

ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .build());
// OR

ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
            .build());

它工作得很好,除非两个联系人中的字段相等。我需要什么来避免这种行为,以及为什么 CONTACT_ID 不足以执行此类操作?

您需要告诉 Android 将您刚刚创建的新 RawContact 与一些(一个或多个)现有 RawContacts.

合并

您可以使用 AggregationException table 为每个这样的 "link" 添加一行。

参见:

代码片段:

Builder builder = ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI);
builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, yourNewRawContact);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, someExistingRawContact);
ContentProviderOperation op = builder.build();