2012-02-23 5 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

이름이 다른 경우에도 생성 된 연락처를 연결하는 방법을 찾았습니까? –

+0

@androiddeveloper 미안 해요.이 일을 멈추고 좋은 대답을 찾지 못했습니다. – Matt

+0

좋아요, 샘플을 사용하여 작동하게 만들었으므로 답변을 게시했습니다. 그것이 내가 모르는 더 많은 질문을 생각하게 만들었다는 것입니다. –

답변

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

+0

내가 아는 한 꽤 까다 롭다. 자동으로 집계되거나 강제로해야한다고 생각합니다. – Samuel

+0

전화가해야 할 일을 수동으로 수행해야하는 것은 어리석은 일입니다. 연락처를 추가하는 방식에 문제가 있다고 생각합니다. – Matt

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. 실제 연락처 ID에 "getLastPathSegment"를 사용하는 올바른 방법입니까?
관련 문제