5

I want to merge the same name contacts with different contact information into one contact to Phone contact list programmatically.

I have also checked this link and seen this answer.

I have used the following code:

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);

I have also tried in a way, firstly get all information of contacts in a list and delete all that contacts. After that add a new contact with all information that I am having with a predefined contactId. This delete all contacts but new contact is not added with a predefined contactId.

You can see here.

Community
  • 1
  • 1
Sarbjit Singh
  • 197
  • 1
  • 3
  • 13
  • 1
    @Kroltan agreed, vote to close + ive flagged for moderators. – undefined Oct 01 '16 at 12:11
  • 1
    @Kroltan It already has the question in the title: the merge of the contacts itself. Suppose you have 2 contacts, and you want to link them, like on many Contacts app, how to do it. He already has the 2 contacts as input (marked as "1" and "2"). Since he failed using the normal API, he tried to merge by modifying the contacts by himself. Why is it closed? – android developer Mar 01 '17 at 08:26
  • @androiddeveloper Look at the date of my comment. Look at the edit history. All the detail was added afterwards. When I commented, the question was *much* worse. At this point, you should just have flagged my comment as obsolete. – This company is turning evil. Mar 01 '17 at 11:16
  • @Kroltan OK, but why does it stay closed, if now it's ok ? – android developer Mar 01 '17 at 11:56
  • @androiddeveloper Because no-one with 3k or more reputation noticed the fact it's now ok. If you have the time, ask around in the [SOCVR chat](http://chat.stackoverflow.com/rooms/41570/so-close-vote-reviewers), you need 5 people with 3k+ rep to vote to reopen. – This company is turning evil. Mar 01 '17 at 12:13
  • @Kroltan OK, I don't know about these rules. Sorry. Didn't mean to upset you so much. – android developer Mar 01 '17 at 12:19
  • @androiddeveloper I'm not upset :), sorry if it sounded so. Just explaining what's the procedure in these cases. – This company is turning evil. Mar 01 '17 at 13:46

3 Answers3

4

I assume you have fetched contacts and build your logic to merge two contacts.

Let say you want to merge two contacts manually whose ContactsContract.RawContacts._ID are masterContactId and contactId.

Now you can merge by following code:

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

ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
    .withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
    .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, masterContactId)
    .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, contactId).build());

try {
    getApplicationContext().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
    e.printStackTrace();
} catch (OperationApplicationException e) {
    e.printStackTrace();
}
Shaishav Jogani
  • 2,111
  • 3
  • 23
  • 33
3

Explanation

https://developer.android.com/guide/topics/providers/contacts-provider
There are 3 tables which holds the data of a contact:

ContactsContract.Contacts
_ID = Unique Id
|----------------------------------|
| _ID | PHOTO_ID | PHOTO_URI | ... |
|----------------------------------|
|  1  | ...      | ...       | ... |
| ... | ...      | ...       | ... |
|----------------------------------|

ContactsContract.RawContacts
_ID        = Unique Id
CONTACT_ID = ContactsContract.Contacts._ID
|------------------------------------------------------|
| _ID | CONTACT_ID | ACCOUNT_NAME | ACCOUNT_TYPE | ... |
|------------------------------------------------------|
|  1  |     1      | +49012345678 | com.whatsapp | ... |
|  2  |     1      | xx@google.de | com.google   | ... |
|------------------------------------------------------|

ContactsContract.Data
_ID            = Unique Id
CONTACT_ID     = ContactsContract.Contacts._ID
RAW_CONTACT_ID = ContactsContract.RawContacts._ID
|-------------------------------------------------------------------|
| _ID | CONTACT_ID | RAW_CONTACT_ID | MIMETYPE | DATA1        | ... |
|-------------------------------------------------------------------|
|  1  |     1      |        1       | PHONE    | +49012345678 | ... |
|  2  |     1      |        2       | PHONE    | +49987654321 | ... |
|-------------------------------------------------------------------|

Example

Lets say you have 3 contacts for John Doe.

  • one device contact
  • one whatsApp contact
  • one telegram contact
Device-Contact
_id    raw_contact_id  contact_id  account_type            mimetype                                                            data1                         data2             data3  
9856   1888            1916        com.htc.android.pcsc    vnd.android.cursor.item/name                                        John Doe                      John              Doe    
12259  1888            1916        com.htc.android.pcsc    vnd.android.cursor.item/phone_v2                                    +49 1511 0000000              2      

Telegram-Contact 
_id    raw_contact_id  contact_id  account_type            mimetype                                                            data1                         data2             data3          
11079  2253            2305        org.telegram.messenger  vnd.android.cursor.item/name                                        John Doe                      John              Doe            
11080  2253            2305        org.telegram.messenger  vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile  123456789                     Telegram Profile  +4915110000000 

WhatsApp-Contact
_id    raw_contact_id  contact_id  account_type            mimetype                                                            data1                         data2             data3                            
12254  2483            2543        com.whatsapp            vnd.android.cursor.item/name                                        John Doe                      John              Doe                             
12255  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.profile                    4915110000000@s.whatsapp.net  WhatsApp          Nachricht an +49 1511 0000000    
12256  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.voip.call                  4915110000000@s.whatsapp.net  WhatsApp          Sprachanruf an +49 1511 0000000  
12257  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.video.call                 4915110000000@s.whatsapp.net  WhatsApp          Videoanruf an +49 1511 0000000   
12258  2483            2543        com.whatsapp            vnd.android.cursor.item/phone_v2                                    +4915110000000                2                 null                             

Then the following method will merge these 3 contacts:

private static void mergeContacts(ArrayList<Contact> contacts, ContentResolver contentResolver) {
    //make sure is sorted in ascending order.
    Collections.sort(contacts, (o1, o2) -> o1.getContactId().compareTo(o2.getContactId()));

    final String rawId = contacts.get(0).getRawContactId(); //ContactsContract.RawContacts._ID
    ArrayList<ContentProviderOperation> ops = new ArrayList<>();
    Contact currentContact;

    for (int index = 1; index < contacts.size(); ++index) {
        currentContact = contacts.get(index);
        ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
                .withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
                .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, rawId)
                .withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, currentContact.getRawContactId()).build());

        Log.d(TAG, "merge contacts: " + rawId + " - " + currentContact.getRawContactId());
    }

    if (!ops.isEmpty()) {
        try {
            ContentProviderResult[] result = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
            Log.d(TAG, "result: " + result.length);
        } catch (Exception e) {
            Log.e(TAG, e.toString(), e);
        }
    }
}
}

Result

And here is the merged contact:

_id    raw_contact_id  contact_id  account_type            mimetype                                                            data1                         data2             data3                           
9856   1888            2543        com.htc.android.pcsc    vnd.android.cursor.item/name                                        John Doe                      John              Doe                            
12259  1888            2543        com.htc.android.pcsc    vnd.android.cursor.item/phone_v2                                    +49 1511 0000000              2                 null                            
11079  2253            2543        org.telegram.messenger  vnd.android.cursor.item/name                                        John Doe                      John              Doe                            
11080  2253            2543        org.telegram.messenger  vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile  123456789                     Telegram Profile  +4915110000000                  
12254  2483            2543        com.whatsapp            vnd.android.cursor.item/name                                        John Doe                      John              Doe                            
12255  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.profile                    4915110000000@s.whatsapp.net  WhatsApp          Nachricht an +49 1511 0000000   
12256  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.voip.call                  4915110000000@s.whatsapp.net  WhatsApp          Sprachanruf an +49 1511 0000000 
12257  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.video.call                 4915110000000@s.whatsapp.net  WhatsApp          Videoanruf an +49 1511 0000000  
12258  2483            2543        com.whatsapp            vnd.android.cursor.item/phone_v2                                    +4915110000000                2                 null                            
Community
  • 1
  • 1
John
  • 136
  • 5
  • Dude, this is an amazing explanation which I needed few months ago. It could spare me so many hours of investigations. Well explained :) – lior_13 Jan 01 '20 at 13:37
0

if you are inserting all contacts in SQLite database then you can use SQLite query to fetch same name contact.

after fetching same name contact delete old contacts from contact list and add new contact with merged details from your app.

Learn Pain Less
  • 2,274
  • 1
  • 17
  • 24