问题描述
我可以使用以下示例片段轻松获取每个联系人的每个电子邮件地址的列表:
//...
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)?.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
}
问题是,由于我已经有了某个联系人的一些信息,有没有办法让我过滤每个联系人的每个电子邮件地址的巨大列表,以便只显示单个联系人的电子邮件地址?
我注意到 Get specific contact information from URI returned from Intent.ACTION_PICK,但该信息相当过时,并且不清楚是否需要 READ_CONTACTS 权限,这是不希望的。
谢谢。
解决方法
通过将意图类型设置为 Email.CONTENT_TYPE
,您似乎是在调用 EMAIL-PICKER 而不是 CONTACT-PICKER。
这意味着用户将在设备的默认联系人应用中选择特定的电子邮件。
然后您从选择器获得的结果不是一个 contactUri
,而是一个 dataUri
- 即指向 {{ 中特定行的 uri 1}} 表,它只允许您获取有关该特定行的信息,在这种情况下,它必须是电子邮件行。
这也意味着通过使用 Data
下的字段,您的投影有点有趣,这无关紧要,因为这些字段是从 Data.CONTENT_URI 继承的,但为了防止混淆,您可能应该将它们替换为:
CommonDataKinds.Phone.X
现在,如果您想要联系人的所有电子邮件而不是单个电子邮件,则不应设置意图类型 - 这将启动一个联系人选择器,它允许您通过检索实体作为获取联系人的电子邮件 + 电话 + 姓名显示here。