Android 获取联系人列表未在 Android 10 中显示
Posted
技术标签:
【中文标题】Android 获取联系人列表未在 Android 10 中显示【英文标题】:Android Getting Contact List is not Showing in Android 10 【发布时间】:2021-07-25 08:04:25 【问题描述】:我正在尝试在 android 中获取联系人列表。它在 andorid 6 和 7 中运行良好。但是当我在 andorid 10 中运行相同的代码时,它没有显示任何单个联系人。 Android 10 有什么变化吗? 这是我的代码:
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()
【问题讨论】:
你有什么错误吗? 【参考方案1】:Runtime permissions 是在 Android 6.0(API 级别 23)中引入的,但从技术上讲,您仍然可以在 Android 6 上运行应用程序,而无需通过针对较低 API 来支持运行时权限,我认为这在 Android 10(甚至更低)。
您的应用是否要求Runtime permission
READ_CONTACTS
才能访问ContactsContract
API?
另外,我认为您的代码在任何 Android 版本中都不能正常工作,您无法查询 CommonDataKinds.Email.CONTENT_URI
然后获取电话号码,我想您只能从该代码中获取姓名和电子邮件。
此外,您的代码效率极低,它会为每个联系人运行一个查询,这可能会导致数百个查询需要一些时间。 您应该用这样的单个查询替换它(同时支持电子邮件和电话):
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
【讨论】:
谢谢。您的代码提供的数据很好,但它显示了双重数据。不知道为什么它显示翻倍的数据。请更新它,这样它就不会显示双重联系。姓名:泽山 姓名:泽山 姓名:阿德南 姓名:阿德南 我们正在遍历数据行列表,这意味着如果一个联系人有 2 封电子邮件和 3 部电话,我们将在 while 循环中访问该联系人 5 次。这就是为什么我使用从联系人 ID 到联系人对象的映射。如果您在 logcat 中看到同一联系人的多个日志,那没关系 但这也会在我们的 ListView 中显示双重联系人数据。 您如何使用此代码输出的map
?因为这是一张地图,所以根据定义,每个联系人 ID 只能出现一次【参考方案2】:
回答我自己的问题。实际上我的代码也可以正常工作。 Android 10 没有 phoneticName 的概念,这就是它崩溃的原因。任何人都可以通过删除 phoneticName 来使用我的代码,它会完美运行。谢谢!
【讨论】:
以上是关于Android 获取联系人列表未在 Android 10 中显示的主要内容,如果未能解决你的问题,请参考以下文章
联系人选择器未在 Android Studio 中提供预期结果
如何从 Android 中的联系人列表中获取联系人?使用联系提供商