I compiled this function to retrieve all email addresses from Android address book from several google results. It works, but it needs ~5 seconds to return 294 addresses. This seems very slow to me.
Especially the many steps and sub-queries seem a bit unnecessary to me. Maybe I can get the resulting array in a single query instead of using the ID and the many sub-queries? Unfortunately, I found no way yet.
TLDR: Is there a way I can retrieve the email addresses faster than with this code?
fun getAllEmails(contentResolver: ContentResolver): String {
val emailList = mutableListOf<String>()
// Query the Contacts table
try {
val cursor = contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
null,
null,
null,
null
)
cursor?.use {
while (it.moveToNext()) {
val id = it.getString(it.getColumnIndex(ContactsContract.Contacts._ID))
// Query the Email table
val emailCursor = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
"${ContactsContract.CommonDataKinds.Email.CONTACT_ID} = ?",
arrayOf(id),
null
)
emailCursor?.use { emailCursor ->
while (emailCursor.moveToNext()) {
val email = emailCursor.getString(emailCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Email.ADDRESS))
emailList.add(email)
}
}
}
}
return emailList.joinToString(",")
} catch (e: Exception) {
e.printStackTrace()
return "" // got no permissions?
}
}
Query directly the emails table.
val cursor = contentResolver.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
arrayOf(ContactsContract.CommonDataKinds.Email.ADDRESS),
null, null, null)
cursor?.use {
while (it.moveToNext()) {
val email = it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS))
emailList.add(email)
}
}
return emailList.joinToString(",")
Add arrayOf(ContactsContract.CommonDataKinds.Email.ADDRESS)
to your cursor to select the emails, and get the email directly with only 1 loop and query.
Let me know if you benchmark it.