0

我可以使用以下示例片段轻松获取每个联系人的每个电子邮件地址的列表:

//...
private val getPerson = registerForActivityResult(PickContact()) {
        it?.also { contactUri ->
            val personDetails = ContactForPerson("", "", "")

            val projection = arrayOf(
                ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY,          //String
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY,//String
                ContactsContract.CommonDataKinds.Email.ADDRESS,             //String
            )

            context?.contentResolver?.query(contactUri, projection, null, null, null)?.apply {
                moveToFirst()
                personDetails.apply {
                    uri = getStringOrNull(0)
                    name = getString(1)
                    email = getStringOrNull(2)
                }
                close()
            }
        }
    }

//...

fab.setOnClickListener {
//...
          getPerson.launch(0)
//...
}

//...

class PickContact : ActivityResultContract<Int, Uri?>() {
    override fun createIntent(context: Context, input: Int?) =
            Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI).also {
                it.type = ContactsContract.CommonDataKinds.Email.CONTENT_TYPE
            }

    override fun parseResult(resultCode: Int, intent: Intent?): Uri? =
        if (resultCode == RESULT_OK) intent?.data else null
}

问题是,由于我已经有一些关于联系人的信息,有没有办法让我过滤每个联系人的每个电子邮件地址的巨大列表,只显示单个联系人的电子邮件地址?

我注意到从 Intent.ACTION_PICK 返回的 URI 中获取特定的联系信息,但是该信息已经过时了,并且不清楚是否需要 READ_CONTACTS 权限,这是不需要的。

谢谢你。

4

1 回答 1

1

通过将意图类型设置为Email.CONTENT_TYPE.

这意味着用户将在设备的默认联系人应用程序中选择特定的电子邮件。

然后您从选择器获得的结果不是a contactUri,而是 a dataUri- 即指向Data表中特定行的 uri,它只允许您获取有关该特定行的信息,在这种情况下它必须是电子邮件排。

这也意味着通过使用 下的字段,您的投影有点有趣CommonDataKinds.Phone.X,这无关紧要,因为这些字段是从 Data.CONTENT_URI 继承的,但是为了防止混淆,您应该将它们替换为:

Data.LOOKUP_KEY, 
Data.DISPLAY_NAME_PRIMARY,
Email.ADDRESS,   

现在,如果您想要所有联系人的电子邮件而不是单个电子邮件,则不应设置意图类型 - 这将启动一个联系人选择器,它允许您通过检索实体来获取联系人的电子邮件 + 电话 + 姓名,如此处所示

于 2021-04-27T07:15:24.923 回答