0

I am developing a sync adapter to sync contacts in the phone with an ERP system. Everything works fine on the emulator, but on the phone I get new phone numbers attached to already existing contacts which were created "by hand".

int rawContactInsertIndex =0;
    // Add new items http://techblogon.com/insert-new-contact-in-android-code-example/
    for (RestAPIContactParser.Entry e : entryMap.values()) {
                    rawContactInsertIndex = batch.size();
...
 batch.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                    .withValue(ContactsContract.RawContacts.SOURCE_ID, e.code)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ACCOUNT_NAME) 
                     rawContactInsertIndex)
                    .build());
... batch.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, e.phone)
                        .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK)
                        .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                                                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
                        .build());

when I delete my account contacts, phone numbers which were inserted also gets deleted from the existing contacts. I even created a new contact on the emulator then tried to sync and everything was fine, new phone numbers weren't attached to the old contacts. Any ideas? edited: Its is not clear what is the database structure of the RawContacts table. Shall do something like

 rawContactInsertIndex =max(ContactsContract.Data.RAW_CONTACT_ID)+1 

and then increment rawContactInsertIndex instead of rawContactInsertIndex = batch.size()?

  • I have deleted all the contacts from phone manually, then imported .vcf from the backup, then installed my sync adapter and the problem has gone. As far as I understand I had some orphans in the contacts. – Anonymous Explorer Aug 11 '17 at 12:22

1 Answers1

0

This is the expected behavior in Android, whenever a new RawContact is inserted, the system will try check if that new RawContact is a duplicate of an existing Contact, and try to join that new RawContact into that existing Contact using the AggregationExceptions table. It uses names, phones and emails to seek our potential existing contacts for merge.

If you don't want your new RawContact to me merged into an existing contacts (though, you should reconsider this is you don't want your users to complain about duplicate contacts), you can add a TYPE_KEEP_SEPARATE rule to AggregationExceptions, specifying your RawContact should not be joined:

ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI)
    .withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_SEPARATE)
    .withValue(AggregationExceptions.RAW_CONTACT_ID1, yourNewRawContact)
    .withValue(AggregationExceptions.RAW_CONTACT_ID2, anExistingRawContact)
    .build();

when I delete my account contacts...

Never delete Contacts that were created as part of your account, as it may delete RawContacts that are not related to your account. Only delete your RawContacts and the related Contacts would be auto-deleted if needed.

Shall do something like

rawContactInsertIndex =max(ContactsContract.Data.RAW_CONTACT_ID)+1

No! The RawContact ID is auto-assigned, don't set it yourself. You should do:

.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

And make sure you applyBatch all related operations together in the same batch.

marmor
  • 27,641
  • 11
  • 107
  • 150
  • Thanks about explaining AggregationExceptions. I deleted my account rawcontacts many times, with no side effects, I always specify my account name and type as query parameters when I delete rawcontacts. – Anonymous Explorer Aug 15 '17 at 14:03
  • yes, that's good, just be careful to delete only `RawContacts` never delete `Contacts`, as you might be deleting other accounts' data. – marmor Aug 15 '17 at 14:05