2012-02-23 11 views
7

this soru ve yanıtını gördüm, ancak telefon bilgilerinin eklenmesi (ve hatta e-posta) hala iletişim bilgilerinin düzgün bir şekilde toplanmasına neden olmaz (Kişiler uygulamasını kontrol ettiğimde, aynı ad altında birden çok giriş görüyorum).Program aracılığıyla eklerken, kişilerin düzgün bir şekilde nasıl toplanacağını nasıl edinirsiniz?

İşte test etmek için kullandığım kod. bunlar otomatik toplayarak değilseniz

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

Oluşturulan kişileri adlarıyla farklı olsa bile nasıl bağlayacağınızı buldunuz mu? –

+0

@androiddeveloper Üzgünüz, bu konuda çalışmayı bıraktım ve hiçbir zaman iyi bir cevap bulamadım – Matt

+0

Tamam, sanırım ben senin örnek kullanarak çalışıyorum, bu yüzden bir cevap yazdım. Şey, benim bilmediğim daha fazla soru düşünmemi sağladı. –

cevap

8

, sen AggregationExceptions tabloya bir satır ekleyerek manuel olarak birleştirebilirsiniz. Eklemeye izin verilmeyen dokümanlarda dikkat ettiğinizden emin olun. Bunun yerine bir güncelleme yapmalısınız. Bu beni iki kez yakaladı. Aşağıdaki kod id en 1 ve 2 ile iki çiğ kişileri birleştirmelidirler:

İşte
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

Her seferinde bir kişi eklediğimde bunu uygulamak zorunda mıyım? Üzerinde çalıştığım program çok fazla sayıda kişi ekleyecektir (bir kısmı veya tümü zaten var olabilir), bu yüzden eklediğim her kişi için aynı olan tüm kişilerin kimliklerini aramak zorunda kalacağım anlamına gelir. Bu istisnayı adlandırın ve ekleyin – Matt

+0

Bildiğim kadarıyla oldukça acımasız. Ya otomatik olarak toplandıklarına ya da onları zorlamanız gerektiğine inanıyorum. – Samuel

+0

Sadece etrafta dolaşmak ve telefonun yapması beklenen şeyi elle yapmak zorunda kalması aptalca görünüyor. Sanırım bağlantı eklediğim şekilde yanlış bir şey olmalı. – Matt

1

ve her biri için farklı verilerle, bağlanması da dahil değiştirilmiş örnek var, bunun işe yaradığını kanıtlamak için:

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

ve sonuç:

enter image description here

ne hakkında emin değilim:

  1. Varolan kişi verileri nasıl alınır ve sonra hangisinin birleştirileceğine nasıl karar verilir? Yerleşik kişiler uygulamasının kişileri birleştirebileceğini fark ettim, ancak ana kontak birleştirilmiş ismin adını alacağı zaman bunları birleştirmiyor. Bunu nasıl yaparım?
  2. Kişiler uygulamasında, UI kullanarak aynı şeyi yapmak yerine, bağlantıyı kaldırma seçeneğinin bulunmadığı durumlar nasıl olur?
  3. Hangi bilgilerin değiştirileceğine, nasıl ekleneceğine, vb. Nasıl karar verir?
  4. Kişileri otomatik olarak birleştiren kurallar nelerdir? Aynı kişi adı yeterlidir, ancak yanlış durumlarda yapabilir (çünkü farklı kişiler soyadı da dahil olmak üzere aynı ada sahip olabilir).
  5. Ham kişi kimliği için "getLastPathSegment" yöntemini kullanmanın gerçekten doğru yolu mu?