Reputation: 591
I am trying to get contact list in android. It is working fine in andorid 6 and 7. But when I run the same code in andorid 10 it is not showing any single contact. Is there any changes in Android 10? Here is my Code:
private fun prepareData() {
contactList.clear()
val cur: Cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null)!!
if (cur.count > 0) {
while (cur.moveToNext()) {
val id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID))
val cur1: Cursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", arrayOf(id), null)!!
while (cur1.moveToNext()) {
//to get the contact data
val name = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
val phoneticName = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHONETIC_NAME))
val phoneNumber = getPhoneNumber()
val email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA))
Log.d("Email", "name: " + name)
Log.d("Email", "phoneticName: " + phoneticName)
Log.d("Email", "phoneNumber: " + phoneNumber)
Log.d("Email", "email: " + email)
contactList.add(Contact(if (name.isNotEmpty()) name else "", if (phoneNumber.isNotEmpty()) phoneNumber else "",
if (phoneticName.isNotEmpty()) phoneticName.trim() else "", if (email.isNotEmpty()) email else ""))
}
cur1.close()
}
}
if (contactList.isEmpty()) {
recyclerView!!.visibility = View.GONE
} else {
recyclerView!!.visibility = View.VISIBLE
mAdapter!!.notifyDataSetChanged()
}
}
Upvotes: 0
Views: 504
Reputation: 591
Answering my own question. Actually my code is also working fine. Android 10 don't have concept of phoneticName and that's why it was crashing. Anyone can use my code by just removing phoneticName it will work perfectly. Thanks!
Upvotes: 0
Reputation: 28179
Runtime permissions were introduced in Android 6.0 (Api level 23), but technically you could still run apps on Android 6 without supporting Runtime Permissions by targeting lower APIs, I don't think that's possible anymore in Android 10 (or even lower).
Does your app asks for Runtime permission
READ_CONTACTS
to be able to access the ContactsContract
APIs?
Also, I don't think your code works well in ANY Android version, you can't query CommonDataKinds.Email.CONTENT_URI
and then get phone numbers, I suppose you only get names + emails from this code.
Also your code is highly inefficient, it runs a query per contact which may result in hundreds of queries taking some time. You should replace this with a single query like this (supporting both emails and phones):
val projection: Array<out String> = arrayOf(Data.CONTACT_ID, Data.DISPLAY_NAME, Data.PHONETIC_NAME, Data.MIMETYPE, Data.DATA1)
val selection: String = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')"
val map = mutableMapOf<Long, Contact>() // map contact-id to Contact object
val cur: Cursor = contentResolver.query(Data.CONTENT_URI, projection, selection, null, null)!!
while (cur.moveToNext()) {
val id = cur.getLong(0)
val name = cur.getString(1)
val phoneticName = cur.getString(2)
val mimetype = cur.getString(3) // this tells us if this row is a phone or email row
val data = cur.getString(4) // may hold either phone or email
Log.d("Contact", id + " " + name + " " + mimetype + " " + data)
val contact = map[id]
if (contact == null) {
contact = Contact(name, "", phoneticName, "") // create a new contact without email or phone
map[id] = contact
}
if (mimetype == Phone.CONTENT_ITEM_TYPE) {
contact.phone = data
} else {
contact.email = data
}
}
Upvotes: 2