Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can programmatically merge two different contacts?(Android)

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.

like image 312
Sarbjit Singh Avatar asked Oct 01 '16 09:10

Sarbjit Singh


2 Answers

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();
}
like image 147
Shaishav Jogani Avatar answered Sep 26 '22 07:09

Shaishav Jogani


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      | [email protected] | 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                    [email protected]  WhatsApp          Nachricht an +49 1511 0000000    
12256  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.voip.call                  [email protected]  WhatsApp          Sprachanruf an +49 1511 0000000  
12257  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.video.call                 [email protected]  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                    [email protected]  WhatsApp          Nachricht an +49 1511 0000000   
12256  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.voip.call                  [email protected]  WhatsApp          Sprachanruf an +49 1511 0000000 
12257  2483            2543        com.whatsapp            vnd.android.cursor.item/vnd.com.whatsapp.video.call                 [email protected]  WhatsApp          Videoanruf an +49 1511 0000000  
12258  2483            2543        com.whatsapp            vnd.android.cursor.item/phone_v2                                    +4915110000000                2                 null                            
like image 28
John Avatar answered Sep 24 '22 07:09

John