Development/Android

[Android / Kotlin] Contact(연락처 연동) 활용 데이터 가져오기

SeungYong.Lee 2022. 12. 2. 11:04
반응형

디바이스 내의 연락처 앱을 사용하다보면, 여러가지 정보들을 포함시킬 수 있는 것을 확인할 수 있습니다.

 

 

프로필 사진, 전화번호, 생일, 메모, 연락처 이름 등 다양한 데이터가 존재하는데,

이 중에서 대표적으로 화면에 보여지고 있는 프로필 사진, 생일, 연락처 이름, 연락처 고유 ID 데이터를

우리가 직접 만든 앱으로 가져올 수 있도록 구현해보겠습니다.

 

 

    <uses-permission android:name="android.permission.READ_CONTACTS"/>

먼저 디바이스 연락처 접근 권한을 얻기 위한 permission tag를 AndroidManifest.xml 파일에 추가해줍니다.

 

 

private fun getContacts() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CONTACTS), 0)
    }

Activity 코드에서는 getContacts() 라는 함수를 생성하여, 사용자에게 권한 허가를 받기 위한 권한 요청 코드를 기입합니다.

해당 함수를 호출하게 되면 제일 먼저 시스템 다이얼로그를 통해 사용자가 연락처 접근에 대한 수락 / 거절을 선택 가능하게 되겠지요.

 

 

	val uri: Uri = ContactsContract.Data.CONTENT_URI

        val projection = arrayOf(
            ContactsContract.CommonDataKinds.Photo.PHOTO_URI,
            ContactsContract.PhoneLookup.LOOKUP_KEY,
            ContactsContract.PhoneLookup._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Event.START_DATE
        )

        val where = ContactsContract.Data.MIMETYPE + "= ? AND " +
                ContactsContract.CommonDataKinds.Event.TYPE + "=" +
                ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY
        val selectionArgs = arrayOf(
            ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE
        )

        val cursur = contentResolver.query(uri, projection, where, selectionArgs, null)

계속 getContacts() 함수에서 작업이 이어집니다.

 

https://developer.android.com/guide/topics/providers/contacts-provider?hl=ko

 

연락처 제공자  |  Android 개발자  |  Android Developers

연락처 제공자 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 연락처 제공자는 사람에 대한 데이터를 저장하는 기기의 중앙 리포지토리를 관리하는 강력하

developer.android.com

안드로이드 공식문서에서 확인 할 수 있는 Uri 기반으로 연락처 데이터를 제공받을 수 있는 Cursor를 구합니다.

ContactsContract.Data.CONTENT_URI

 

 

projection array에는 우리가 필요로 하는 데이터 요소를 지정할 수 있습니다.

ContactsContract.Contacts.DISPLAY_NAME, //연락처 이름
ContactsContract.PhoneLookup.LOOKUP_KEY, //연락처 검색을 위한 Key 값
ContactsContract.CommonDataKinds.Photo.PHOTO_URI, //연락처 프로필 
ContactsContract.CommonDataKinds.Event._ID, //해당 연락처 정보의 고유 ID
ContactsContract.CommonDataKinds.Event.START_DATE //기념일 또는 생일 날짜 값

 

 

where는 쿼리에 사용되는 조건절입니다.

우리가 원하는 데이터는 MIMETYPE이며, TYPE_BIRTHDAY와 동일한 TYPE으로 쿼리해야 생일 날짜 값을 받을 수 있습니다.

val where = ContactsContract.Data.MIMETYPE + "= ? AND " +
        ContactsContract.CommonDataKinds.Event.TYPE + "=" +
        ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY

 

 

selectionArgs는 where 절에 실제로 전달할 값입니다.

MIMETYPE 기반으로 데이터를 가져오기 때문에 CONTENT_ITEM_TYPE을 전달해줍니다.

val selectionArgs = arrayOf(
    ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE
)

 

 

이렇게 생성한 Cursor를 통해 각 컬럼에 해당하는 인덱스 값을 가져와 실제 인덱스에 해당하는 값들을 추출합니다.

    val contactIdColumn = cursor?.getColumnIndex(ContactsContract.CommonDataKinds.Event._ID) ?: 0
    val birthColumn = cursor?.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE) ?: 0
    val contactNameColumn = cursor?.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME) ?: 0
    val lookUpKeyColumn = cursor?.getColumnIndex(ContactsContract.PhoneLookup.LOOKUP_KEY) ?: 0
    val photoUriColumn = cursor?.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO_URI) ?: 0
        
    if (cursor != null) {
        while (cursor.moveToNext()) {
            val id = cursor.getString(contactIdColumn)
            val contactName = cursor.getString(contactNameColumn)
            val birth = cursor.getString(birthColumn).convertToDateList() //custom func
            val lookUpKey = cursor.getString(lookUpKeyColumn)
            val photoUri = cursor.getString(photoUriColumn) ?: ""
        }
    }

 

 

최종적으로 로그를 찍어보면, 이렇게 데이터를 반환하는 것을 확인할 수 있습니다.

프로필 사진은 특별하게 지정된 것이 없다면 null로 수신받네요.

또한 생일 설정 시, 연도를 지정하지 않았다면 --11-22, 설정했다면 2022-11-22 형태로 수신 받습니다.

 

 

프로필 사진의 경우에는 수신 받은 포토 Uri를 그대로 Glide에 적용하여 사용 가능합니다.

    Glide.with(context)
        .load(photoUrl)
        .into(holder.linkImg)

 

 

LookUpKey와 ID 같은 경우에는 다음과 같이 getLookupUri(id: Long, key: String)을 활용하여
사용자의 연락처 프로필로 바로 이동할 수 있는 Uri 생성이 가능합니다.

val contactUri = ContactsContract.Contacts.getLookupUri(contactId.toLong(), url)

val intent = Intent(Intent.ACTION_VIEW)
    intent.data = contactUri
    activity?.startActivity(intent)

 

반응형