我需要从Android设备查询我正在处理的项目的联系人,我需要以可以在应用程序中的实例与电话簿中的联系人之间链接的方式保存它们。
我发现每个联系人的CONTACT_ID(这是对_ID的引用(可能会在设备之间更改,因此如果我切换到其他Android设备,该ID将无效。
临时解决方案正在使用联系人的SOURCE_ID,这是一个字符串,用于将此行唯一标识为其源客户。该解决方案非常好,因为如果联系人来自(例如(Google帐户,它将在我拥有的每台设备上保持完全相同的ID。问题是 -并非每个联系人都有SOURCE_ID。
也可以使用特定联系人的数据作为过滤器来查询特定联系人,该过滤器可以用作唯一ID,例如他的电话号码等...然而,每条数据都有一个缺陷。例如:一个联系人可能有多个电话号码(这仍然可以(,并且号码可以变化(例如:202-555-0105 与 +1-202-555-0105 相同,也与 (202( 555 0105 相同,也是2025550105(。
编辑:也不是每个联系人都有电话号码,那又怎样?
因此,在给定问题之后 -
如何获取Android电话簿中联系人的唯一ID,以便它们在跨设备上相同?
注意:默认情况下,在 IOS 上是可能的(请参阅文档(-
代表同一人的不同帐户中的联系人可能会自动链接在一起。链接的联系人在 OS X 和 iOS 应用程序中显示为统一联系人。统一联系人是合并为一个联系人的链接联系人集的内存中的临时视图。
默认情况下,联系人框架返回统一联系人。每个提取的统一联系人 (CNContact( 对象都有自己的唯一标识符,该标识符不同于链接联系人集中任何单个联系人的标识符。统一联系人的重新获取应使用其标识符完成。
你要找的是LOOKUP_KEY
一个不透明值,其中包含有关如何在联系人的行 ID 因同步或聚合而发生更改时查找联系人的提示。
若要使联系人LOOKUP_KEY
遍历联系人,下面是一个示例:
注意:<uses-permission android:name="android.permission.READ_CONTACTS" />
是必需的。
val contentUri = ContactsContract.Contacts.CONTENT_URI
val cursor = context?.contentResolver?.query(contentUri, null, null, null, null)
if (cursor != null) {
while (cursor.moveToNext()) {
val id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
val name =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY))
val lookupKey =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY))
}
}
cursor?.close()
以下是您如何检索与LOOKUP_KEY
的联系人:
val lookupKey = "0r1-3C263544104632"
val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey)
val uri = ContactsContract.Contacts.lookupContact(contentResolver, lookupUri)
val cursor = context?.contentResolver?.query(uri, null, null, null, null)
if (cursor != null) {
while (cursor.moveToNext()) {
val id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
val name =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY))
}
}
cursor?.close()
}
请注意,联系人必须同步才能避免重新生成LOOKUP_KEY
。
保证为每个联系人生成LOOKUP_KEY
,但是,如果未设置帐户且未同步,则每当修改联系人时,都会重新生成LOOKUP_KEY
。
考虑到这一点,如果设备已同步,您将始终拥有唯一的LOOKUP_KEY
。LOOKUP_KEY
依赖于Google Cloud,这可能是Apple使用的解决方案。
Android设备不太可能没有Google帐户,因为大多数Android用户都依赖Google服务。
恐怕这是拥有唯一标识符的最佳方法,但是,如果您愿意,您可以将用户电话号码与其他联系方式相结合,但这种方法不能保证有效,因为联系人可能会更改。如果您的用户已注册并且您将拥有他们的信息,那么您可以在后端检查哪些哈希值符合您的期望,然后根据您自己的同步进行工作。
如果您想尝试一下,我创建了一个带有实现的示例应用程序,您可以在其中查看联系人并找到查找键以及使用查找键检索联系人。
我还建议您查看SyncAdapter。