I saw this question and answer, but adding the phone information (and even email) still does not cause the contact information to aggregate properly (when I check the People app, I can see multiple entries under the same name).
Here is the code I use to test it.
//get the account
Account acct = null;
Account[] accounts = AccountManager.get(getContext()).getAccounts();
for (Account acc : accounts){
acct = acc;
}//assuming there's only one account in there (in my case I know there is)
//loop a few times, creating a new contact each time. In theory, if they have the same name they should aggregate
for(int i=0; i<3; i++){
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, acct.type)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, acct.name)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.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, "ContactName")
.build());
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, "1234567890")
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 1)
.build());
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.DATA, "[email protected]")
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, 1)
.build());
try{
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
Log.e("Contacts", "Something went wrong during creation! " + e);
e.printStackTrace();
}
}
If they aren't aggregating automatically, you can aggregate them manually by adding a row to the AggregationExceptions table. Make sure you notice in the docs that insert is not allowed. You have to do an update instead. That's caught me twice now. The following code should aggregate the two raw contacts with id's 1 and 2:
ContentValues cv = new ContentValues();
cv.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
cv.put(AggregationExceptions.RAW_CONTACT_ID1, 1);
cv.put(AggregationExceptions.RAW_CONTACT_ID2, 2);
getContentResolver().update(AggregationExceptions.CONTENT_URI, cv, null, null);
Here's a modified sample including the linking, and with different data for each, to prove that it works :
Account acct = null;
Account[] accounts = AccountManager.get(this).getAccounts();
for (Account acc : accounts) {
acct = acc;
}
//loop a few times, creating a new contact each time. In theory, if they have the same name they should aggregate
final ArrayList<Uri> newlyCreatedContactsUris = new ArrayList<>();
for (int i = 0; i < 2; i++) {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, acct == null ? null : acct.type)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, acct == null ? null : acct.name)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.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, "ContactName" + i)
.build());
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, Integer.toString(123456789 * (i + 1)))
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 1)
.build());
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.DATA, "email" + i + "@address.com")
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, 1)
.build());
try {
final ContentProviderResult[] contentProviderResults = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
newlyCreatedContactsUris.add(contentProviderResults[0].uri);
Log.d("AppLog", "done creating new contacts data");
} catch (Exception e) {
Log.e("AppLog", "Something went wrong during creation! " + e);
e.printStackTrace();
}
}
//Note: seems we can only link 2 contacts data together, not more
ArrayList<ContentProviderOperation> mergeOps = new ArrayList<>();
mergeOps.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER)
.withValue(AggregationExceptions.RAW_CONTACT_ID1, newlyCreatedContactsUris.get(0).getLastPathSegment())
.withValue(AggregationExceptions.RAW_CONTACT_ID2, newlyCreatedContactsUris.get(1).getLastPathSegment())
.build());
try {
final ContentProviderResult[] contentProviderResults2 = getApplicationContext().getContentResolver().applyBatch(ContactsContract.AUTHORITY, mergeOps);
Log.d("AppLog", "done merging");
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
And the result:
What I'm not sure about is:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With