728x90

Android Contacts 를 검색하고 동일 정보가 있으면 삭제하고 신규로 데이터를 저장하는 로직이 있어서 아무 생각없이 잘 될 것이라는 믿음(?)으로 소스를 사용하다가 주소록을 2,000 개 이상 동시 저장하는 걸 테스트 하는데 너무 느려서 구글링으로 예제 소스 하나 받아서 테스트를 해보니 동일한 자료가 엄청나게 저장되어 있는 걸 알았다.

삼성폰이 기본 제공하는 연락처 앱에서는 데이터가 딱 저장한 개수만큼만 보인다.

데이터 삭제가 제대로 되는지 확인해봤더니 삭제가 안되고 있더라.

계속 삽질을 하다가 Easy Contacts Delete 라는 어플을 받아서 전체를 선택하고 삭제를 했더니 모든 데이터가 삭제되었다.


연락처(Contacts) 에 대한 기본 개념이 부족해서 해결이 제대로 안되는 것이라 집중적으로 관련 자료를 검색하고 책을 보면서 정리하고 테스트 해보고 있다.

Display_Name 으로 검색한 ContactID 와 Phone Number 로 검색한 ContactID 를 정확하게 구현해주어야 한다는 걸 테스트를 통해서 알게되었고, Phone Number 기준으로 얻은 ContactID 로 삭제가 잘 된다는 걸 알았다.


도전의 절반은 스키마를 마스터하고, 각 테이블이 다른 테이블과 어떻게 상호 작용하는지를 이해하는데 있다.


주소록 DB는 /data/data/com.android.providers.contacts/databases/contacts2.db 에 있는데 접근이 불가능하다.

contacts database는 Provider URI 를 통해서 접근할 수 있다.

Stackoverflow 보면 https://developer.android.com/guide/topics/providers/contacts-provider.html 사이트 참조하라고 나온다.


Contacts API 2.0 에서는, 연락처(Contacts)은 다음 세 테이블로 구성되어 있다.


  ContactsContract.Contacts table

 - 고유한 사용자(people) 정보를 표시하는 테이블

 - https://developer.android.com/reference/android/provider/ContactsContract.Contacts.html 칼럼 확인


  ContactsContract.RawContacts table

 - user account and type 을 기준으로, 한 사용자 정보 요약을 포함하는 테이블

 - https://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html 에서 칼럼 확인

 - ContactsContract.RawContacts.CONTACT_ID = Contacts._ID 값과 일치


  ContactsContract.Data table

 - E-Mail 주소나 휴대폰번호 같은 RawContacts 테이블의 세부 정보를 포함하는 테이블
 - ContactsContract.Data.RAW_CONTACT_ID = ContactsContract.RawContacts._ID 값과 일치

 - https://developer.android.com/reference/android/provider/ContactsContract.Data.html 에서 칼럼 확인

 - 15개의 일반 열 중에서 DATA1부터 DATA15까지는 일반적으로 이용할 수 있고 이외에 추가로 마련된 네 개의 일반 열, 즉 SYNC1부터 SYNC4까지는 동기화 어댑터 전용이다.

 - 표시 이름, 전화 번호, 이메일, 우편 주소, 사진 및 웹사이트 세부 정보 행은 모두 ContactsContract.Data 테이블에서 찾을 수 있다.


모든 테이블에는 테이블명._ID 가 있다.


위 도식도에 나온 ID 칼럼이 서로 어떻게 연관되어 있는지를 아는것이 가장 중요하다.

데이터를 수정(Update)하거나 삭제(Delete)할 때 정확하게 정보를 업데이트할 수 있다.

즉 rawContactId 값을 구하는 걸 잘못 구하면 데이터 수정/삭제가 제대로 안된다는 것이다.

이 개념 이해하느라고 정말 많은 시간을 할애하였다.

구글링해도 이런 내용은 나오지 않고 그냥 소스 코드 예제만 좀 나온다.

검색 키워드 찾는 방법을 잘못하니까 예제 찾기도 쉽지 않더라.


원시 연락처의 이름은 ContactsContract.RawContacts에 있는 자신의 행에 저장되지 않고,

ContactsContract.CommonDataKinds.StructuredName 행에 있는 ContactsContract.Data 테이블에 저장된다.
원시 연락처의 데이터는 원시 연락처의 _ID 값과 연결된ContactsContract.Data 행에 저장된다.
하나의 원시 연락처에 같은 유형 데이터의 인스턴스가 여러 개 있을 수 있다.
ㅇ MIMETYPE
  - 사용자 지정 MIME 유형으로 표현된다.
  - 연락처 제공자는 ContactsContract.CommonDataKinds의 서브클래스에서 정의된 MIME 유형을 사용한다.

ㅇ 연락처 제공자는 기존 연락처 어느 것과도 일치하지 않는 새로운 원시 연락처가 추가되면 새로운 연락처를 생성한다.
  애플리케이션이나 동기화 어댑터가 기존 연락처와 일치하는 새로운 원시 연락처를 생성하면, 새로운 원시 연락처는 기존 연락처에 통합된다.
ㅇ 연락처 제공자가 연락처를 자동으로 관리하므로, 통합이나 동기화에 응답하여 연락처 행의 _ID 값을 변경할 수도 있다.
ㅇ 사용자 프로필에 액세스하기 위한 상수는 ContactsContract.Profile 클래스에서 이용할 수 있다.
  - 사용자 프로필에 액세스하려면 특수 권한이 필요하다.
  - android.Manifest.permission#READ_PROFILE과 android.Manifest.permission#WRITE_PROFILE 권한이 필요
  - 권한 android.Manifest.permission#READ_PROFILE을 사용하면 개발자가 기기 사용자의 개인 식별 데이터에 액세스할 수 있게 해준다.



참고

특정 블로그에서만 찾은 자료가 아닌지라 출처는 생각나는 것만 남긴다.

http://www.javased.com/index.php?source_dir=android-client_1/src/com/googlecode/asmack/contacts/ContactDataMapper.java

안드로이드 연락처 초성검색 소스 : http://www.androidpub.com/45681

http://blog.mready.net/2012/09/android-contacts/ 에 나온 예제를 가지고 ContactHelper.java 클래스 파일을 만드는데 활용하면 좋을 거 같다.

블로그 이미지

Link2Me

,