Skip to content

Instantly share code, notes, and snippets.

@rovkinmax
Last active November 18, 2016 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rovkinmax/51a95bbe2190bef04970ca4e25198535 to your computer and use it in GitHub Desktop.
Save rovkinmax/51a95bbe2190bef04970ca4e25198535 to your computer and use it in GitHub Desktop.
Example for reading contacts in Android
data class Contact(val id: String = "", val name: String = "", val photoUri: String = "", var phoneNumber: String = "", val typeStringRes: Int = 0)
class ContactRepository {
companion object {
private val CONTACTS_PROJECTION = arrayOf(Contacts._ID,
Contacts.DISPLAY_NAME_PRIMARY,
Contacts.PHOTO_THUMBNAIL_URI,
Contacts.HAS_PHONE_NUMBER)
private val DATA_PROJECTION = arrayOf(ContactsContract.Data.CONTACT_ID,
ContactsContract.Data.DATA1,
ContactsContract.Data.MIMETYPE,
CommonDataKinds.Phone.TYPE)
}
fun getContacts(resolver: ContentResolver): Observable<Contact> {
return Observable.fromEmitter<Contact>({ emitter ->
val contactsCursor = getContactsCursor(resolver)
val phonesCursor = getPhonesCursor(resolver)
fetchContactsFromCursor(contactsCursor, phonesCursor, emitter)
emitter.onCompleted()
}, BackpressureMode.BUFFER)
}
private fun getContactsCursor(resolver: ContentResolver): Cursor? {
return resolver.query(
Contacts.CONTENT_URI,
CONTACTS_PROJECTION,
"${Contacts.HAS_PHONE_NUMBER} >0",
null,
"${Contacts._ID} ASC")
}
private fun getPhonesCursor(resolver: ContentResolver): Cursor? {
val args = arrayOf(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
val data = resolver.query(
ContactsContract.Data.CONTENT_URI,
DATA_PROJECTION,
"${ContactsContract.Data.MIMETYPE}=?",
args,
"${ContactsContract.Data.CONTACT_ID} ASC")
return data
}
fun getContactById(resolver: ContentResolver, id: String): Observable<Contact> {
return Observable.fromEmitter({ emitter ->
val contactCursor = getContactCursor(id, resolver)
val phonesCursor = getContactPhonesCursor(id, resolver)
fetchContactsFromCursor(contactCursor, phonesCursor, emitter)
emitter.onCompleted()
}, BackpressureMode.BUFFER)
}
private fun getContactCursor(id: String, resolver: ContentResolver): Cursor? {
val args = arrayOf(id)
return resolver.query(
Contacts.CONTENT_URI,
CONTACTS_PROJECTION,
"${Contacts.HAS_PHONE_NUMBER} >0 AND ${Contacts._ID} =?",
args,
null)
}
private fun getContactPhonesCursor(id: String?, resolver: ContentResolver): Cursor? {
val args = arrayOf(id, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
val data = resolver.query(
ContactsContract.Data.CONTENT_URI,
DATA_PROJECTION,
"${ContactsContract.Data.CONTACT_ID}=? AND ${ContactsContract.Data.MIMETYPE}=?",
args,
null)
return data
}
private fun fetchContactsFromCursor(contactsCursor: Cursor?, phonesCursor: Cursor?, emitter: Emitter<Contact>) {
try {
if (contactsCursor != null && phonesCursor != null) {
var id: String = ""
var name: String = ""
var photoUri: String = ""
while (phonesCursor.moveToNext() && contactsCursor.isAfterLast.not()) {
val phoneNumber = phonesCursor.getStringByColumn(ContactsContract.Data.DATA1)
val type = phonesCursor.getIntByColumn(CommonDataKinds.Phone.TYPE)
val typeStringRes = CommonDataKinds.Phone.getTypeLabelResource(type)
val contactId = phonesCursor.getStringByColumn(ContactsContract.Data.CONTACT_ID)
if (id.equals(contactId).not()) {
contactsCursor.moveToNext()
id = contactsCursor.getStringByColumn(Contacts._ID) ?: ""
name = contactsCursor.getStringByColumn(Contacts.DISPLAY_NAME_PRIMARY) ?: ""
photoUri = contactsCursor.getStringByColumn(Contacts.PHOTO_THUMBNAIL_URI) ?: ""
}
if (phoneNumber.isNullOrEmpty().not()) {
val contact = Contact(id, name, photoUri, phoneNumber!!, typeStringRes)
emitter.onNext(contact)
}
}
}
} finally {
contactsCursor?.close()
phonesCursor?.close()
}
}
private fun Cursor.getStringByColumn(column: String): String? {
try {
return getString(getColumnIndex(column))
} catch(e: Exception) {
return null
}
}
private fun Cursor.getIntByColumn(column: String): Int {
try {
return getInt(getColumnIndex(column))
} catch(e: Exception) {
return ResourcesUtil.ILLEGAL_RES
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment