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 联系人列表获取地址

Android - 获取所有联系人列表时出错

联系人选择器未在 Android Studio 中提供预期结果

如何从 Android 中的联系人列表中获取联系人?使用联系提供商

如何在 Android 中获取 SPEED Dial 联系人列表?

Android从联系人列表中获取电话号码