如何在Android中以编程方式合并两个不同的联系人?

5
我希望能够通过编程将通讯录中姓名相同但信息不同的联系人合并为一个联系人。
我已经查看了这个链接,并看到了这个答案
我使用了以下代码:
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);

我也尝试过一种方法,首先将联系人列表中的所有信息获取到并删除这些联系人。然后使用预定义的contactId添加一个包含所有信息的新联系人。这会删除所有联系人,但是无法添加具有预定义contactId的新联系人。

您可以在这里看到。


1
@Kroltan同意,投票关闭+我已经为管理员标记了。 - undefined
1
@Kroltan 它的标题已经包含了问题:联系人的合并本身。假设你有2个联系人,你想要将它们关联起来,就像许多联系人应用程序一样,该怎么做呢?他已经将这两个联系人作为输入(标记为“1”和“2”)。由于他在使用正常的API时失败了,他尝试通过自己修改联系人来进行合并。为什么会关闭呢? - android developer
@androiddeveloper 看看我的评论日期。再看看编辑历史记录。所有细节都是事后添加的。当我发表评论时,问题还要糟糕得多。此时,您应该将我的评论标记为过时。 - Kroltan
@Kroltan 好的,但是如果现在没问题了,为什么它还是关闭的呢? - android developer
@androiddeveloper 因为没有任何拥有3k或更高声望的人注意到现在已经可以了。如果你有时间,请在SOCVR聊天室里询问,你需要5个拥有3k+声望的人投票重新开放。 - Kroltan
显示剩余2条评论
3个回答

4

我假设您已经获取了联系人并构建了合并两个联系人的逻辑。

比如说,您想要手动合并两个联系人,这两个联系人的 ContactsContract.RawContacts._ID 分别为 masterContactIdcontactId

现在,您可以使用以下代码进行合并:

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的代码,但是没有得到任何输出。手机上存在重复联系人。 - Sarbjit Singh
发布你的代码。你是如何获取联系人列表和其他信息的? - Shaishav Jogani
“masterContactId”指的是它的查找键吗?您能否发布一些附加代码?您如何将多个联系人链接在一起? - android developer
masterContactId 表示第一个联系人的ID,而 contactId 是第二个联系人的ID。 - Sarbjit Singh
1
请问您能否定义一下如何合并多个联系人吗? - mehul chauhan
@mehulchauhan,请查看我的回答以合并多个联系人。 - John

3

说明

https://developer.android.com/guide/topics/providers/contacts-provider
有三个表格保存联系人的数据:

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 | ... |
|-------------------------------------------------------------------|

例子

假设您有三个与John Doe相关的联系人。

  • 一个设备联系人
  • 一个 WhatsApp 联系人
  • 一个 Telegram 联系人
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                             

接下来的方法将合并这3个联系人:

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

结果

下面是合并后的联系人:

_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                            

哥们,这是一个非常棒的解释,我几个月前就需要了。它可以为我节省很多调查时间。讲解得非常清楚 :) - lior_13

0

如果您正在将所有联系人插入SQLite数据库,则可以使用SQLite查询来获取相同名称的联系人。

在获取相同名称的联系人后,从联系人列表中删除旧联系人,并添加具有来自您的应用程序的合并详细信息的新联系人。


你在这个想法上卡住了吗? - Learn Pain Less
在合并联系人详细信息并添加新联系人时,请注意 @pawneshwar。 - Sarbjit Singh
你有合并的细节吗? - Learn Pain Less

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接