2012-02-23 74 views
7

我看到this问题和答案,但添加电话信息(甚至是电子邮件)仍然不会导致联系人信息正确聚合(当我检查人员应用程序时,我可以看到同名多个条目)。如何在以编程方式添加联系人时正确汇总联系人?

这是我用来测试它的代码。

//get the account 
Account acct = null; 
Account[] accounts = AccountManager.get(getContext()).getAccounts(); 
for (Account acc : accounts){ 
    acct = acc; 
}//assuming there's only one account in there (in my case I know there is) 

//loop a few times, creating a new contact each time. In theory, if they have the same name they should aggregate 
for(int i=0; i<3; i++){ 
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 
    ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) 
       .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, acct.type) 
       .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, acct.name) 
       .withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT) 
       .build()); 
    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "ContactName") 
       .build()); 
    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "1234567890") 
       .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 1) 
       .build()); 
    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.Email.DATA, "[email protected]") 
       .withValue(ContactsContract.CommonDataKinds.Email.TYPE, 1) 
       .build()); 

    try{   
     getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); 
    } 
    catch (Exception e) { 
     Log.e("Contacts", "Something went wrong during creation! " + e); 
     e.printStackTrace(); 
    } 
} 
+0

您是否发现如何链接生成的联系人,即使他们的名字不同? – 2017-03-01 09:06:00

+0

@androiddeveloper对不起,我停止对此工作,从来没有找到一个好的答案 – Matt 2017-03-01 14:06:20

+0

好吧,我想我使用你的示例工作,所以我已经发布了一个答案。问题是它让我想到了更多我不知道的问题。 – 2017-03-01 15:39:39

回答

8

如果它们没有自动地收集,您可以手动添加一个行到AggregationExceptions表它们聚集。确保你注意到文档中不允许插入。您必须改为更新。现在我抓了两次。下面的代码应集合体的ID 1和2的两个原始接触:

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

那么我每次添加联系人时都需要应用此操作?我正在处理的程序将添加大量联系人(部分或全部联系人可能已经存在),所以这意味着对于我添加的每个联系人,我必须查找具有相同联系人的所有联系人的ID名称并添加此异常? – Matt 2012-02-23 19:50:30

+0

据我所知,这是非常严峻的。我相信他们会自动汇总,或者你必须强制他们。 – Samuel 2012-02-23 20:25:43

+0

这似乎很愚蠢,必须四处走动,并手动做手机预计要做的事情。我认为我添加联系人的方式必须有问题。 – Matt 2012-02-24 15:01:44

1

下面是包括联的改性样品,并用每个不同的数据,以证明它的工作原理:

Account acct = null; 
    Account[] accounts = AccountManager.get(this).getAccounts(); 
    for (Account acc : accounts) { 
     acct = acc; 
    } 
    //loop a few times, creating a new contact each time. In theory, if they have the same name they should aggregate 
    final ArrayList<Uri> newlyCreatedContactsUris = new ArrayList<>(); 
    for (int i = 0; i < 2; i++) { 
     ArrayList<ContentProviderOperation> ops = new ArrayList<>(); 
     ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) 
       .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, acct == null ? null : acct.type) 
       .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, acct == null ? null : acct.name) 
       .withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT) 
       .build()); 
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "ContactName" + i) 
       .build()); 
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, Integer.toString(123456789 * (i + 1))) 
       .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 1) 
       .build()); 
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) 
       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) 
       .withValue(ContactsContract.Data.MIMETYPE, 
         ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) 
       .withValue(ContactsContract.CommonDataKinds.Email.DATA, "email" + i + "@address.com") 
       .withValue(ContactsContract.CommonDataKinds.Email.TYPE, 1) 
       .build()); 

     try { 
      final ContentProviderResult[] contentProviderResults = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); 
      newlyCreatedContactsUris.add(contentProviderResults[0].uri); 
      Log.d("AppLog", "done creating new contacts data"); 
     } catch (Exception e) { 
      Log.e("AppLog", "Something went wrong during creation! " + e); 
      e.printStackTrace(); 
     } 
    } 
    //Note: seems we can only link 2 contacts data together, not more 
    ArrayList<ContentProviderOperation> mergeOps = new ArrayList<>(); 
    mergeOps.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI) 
      .withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER) 
      .withValue(AggregationExceptions.RAW_CONTACT_ID1, newlyCreatedContactsUris.get(0).getLastPathSegment()) 
      .withValue(AggregationExceptions.RAW_CONTACT_ID2, newlyCreatedContactsUris.get(1).getLastPathSegment()) 
      .build()); 
    try { 
     final ContentProviderResult[] contentProviderResults2 = getApplicationContext().getContentResolver().applyBatch(ContactsContract.AUTHORITY, mergeOps); 
     Log.d("AppLog", "done merging"); 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } catch (OperationApplicationException e) { 
     e.printStackTrace(); 
    } 

而结果:

enter image description here

什么我不知道的是:

  1. 如何获取现有的联系人数据,然后决定要合并哪个?我注意到内置的联系人应用可以合并联系人,但有时在主要联系人将采用合并联系人的名称时不会将它们合并。我会怎么做?
  2. 如何进入联系人应用程序,没有选择取消链接,而不是使用UI做同样的事情?
  3. 它如何决定要替换哪些信息,要添加哪些信息......?
  4. 自动合并联系人的规则是什么?看起来相同的联系人姓名已经足够,但它可以在错误的情况下执行(因为不同的人可以使用相同的姓名,甚至包括姓氏)。
  5. 真正的使用“getLastPathSegment”作为原始联系人ID的正确方法是什么?
相关问题