-1

I am trying to link all the contacts in the phone with my application . and then launch my application from contact app. In api < 23 it works fine. But in api >23 the contacts get duplicated .so let me know anyone tried this !!.. Here is what i tried..!

 public class ContactsSync extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {
        String name, number, id;
        for (int i = 0; i <=mIDs.size(); i++) {
            //name = mNames.get(i);
            id = mIDs.get(i);
            number = mNumbers.get(i);
            ContactsManager.addContact(Paymoney.this, new MyContact(id, number));
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        getContactDataAfter();
    }
}

public static void addContact(Context context, MyContact contact){

    ContentResolver resolver = context.getContentResolver();
    boolean mHasAccount = isAlreadyRegistered(resolver, contact.Id);

    if(mHasAccount){
    } else {

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

        // insert account name and account type
        ops.add(ContentProviderOperation
                .newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, Constants.ACCOUNT_NAME)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE)
                .withValue(ContactsContract.RawContacts.AGGREGATION_MODE,
                        ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
                .build());

       ops.add(ContentProviderOperation
                .newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(CommonDataKinds.Phone.NUMBER, contact.number)
                .build());


        ops.add(ContentProviderOperation
                .newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE, MIMETYPE)
                .withValue(ContactsContract.Data.DATA1, 12345)
                .withValue(ContactsContract.Data.DATA2, "user")
                .withValue(ContactsContract.Data.DATA3, "Send Money")
                .build());
            resolver.applyBatch(ContactsContract.AUTHORITY, ops);
gStephin
  • 332
  • 3
  • 20

1 Answers1

0

You need to explicitly aggregate your new RawContact into an existing (raw) contact:

ops.add(ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI)
   .withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER)
   .withValue(AggregationExceptions.RAW_CONTACT_ID1, yourNewRawContactId)
   .withValue(AggregationExceptions.RAW_CONTACT_ID2, someExistingRawContactId)
   .build());

Of course you can use withValueBackReference to run this operation in the same batch while creating the new RawContact

marmor
  • 27,641
  • 11
  • 107
  • 150
  • withValueBackReference is working for the api <23 . i tried the above code but still duplication is there – gStephin Aug 08 '17 at 09:22
  • did you use proper value for `someExistingRawContactId` ? you need to set it to an **existing** raw contact id, so the system will join these two raw-contacts into one-contact – marmor Aug 08 '17 at 09:28