网页版联系人选择器

借助 Contact Picker API,用户可以轻松分享其联系人列表中的联系人。

什么是 Contact Picker API?

自(几乎)有史以来,访问移动设备上的用户联系人一直是 iOS/Android 应用的一项功能。这是我从 Web 开发者那里听到的最常见的功能请求之一,也是他们构建 iOS/Android 应用的关键原因。

Contact Picker API 规范自 Chrome 80 在 Android M 或更高版本上推出以来,一直是一种按需 API,可让用户从其联系人列表中选择条目,并与网站分享所选条目的有限详细信息。用户可以随时随地只分享自己想分享的内容,并且可以更轻松地与亲朋好友联系。

例如,基于 Web 的电子邮件客户端可以使用“联系人选择器”API 来选择电子邮件的收件人。IP 语音应用可以查找要拨打的电话号码。或者,社交网络可以帮助用户发现哪些好友已经加入。

使用 Contact Picker API

Contact Picker API 需要通过一个带有选项参数的方法调用来指定所需的联系信息类型。第二种方法会告知您底层系统将提供哪些信息。

功能检测

如需检查是否支持 Contact Picker API,请使用:

const supported = ('contacts' in navigator && 'ContactsManager' in window);

此外,在 Android 上,联系人选择器需要 Android M 或更高版本。

打开联系人选择器

Contact Picker API 的入口点为 navigator.contacts.select()。 调用时,它会返回一个 promise 并显示联系人选择器,让用户选择要与网站分享的联系人。选择要分享的内容并点击完成后,该 promise 会解析为用户选择的联系人数组。

调用 select() 时,您必须提供一个属性数组作为第一个参数(允许的值为 'name''email''tel''address''icon' 中的任意一个),并可选择性地提供第二个参数,以指明是否可以选择多个联系人。

const props = ['name', 'email', 'tel', 'address', 'icon'];
const opts = {multiple: true};

try {
  const contacts = await navigator.contacts.select(props, opts);
  handleResults(contacts);
} catch (ex) {
  // Handle any errors here.
}

只能从安全的顶级浏览上下文中调用 Contacts Picker API,并且与其他强大的 API 一样,它需要用户手势。

检测可用属性

如需检测哪些属性可用,请调用 navigator.contacts.getProperties()。它会返回一个 Promise,该 Promise 会解析为一个字符串数组,用于指明哪些属性可用。例如:['name', 'email', 'tel', 'address']。您可以将这些值传递给 select()

请注意,属性并非始终可用,并且可能会添加新属性。未来,其他平台和联系人来源可能会限制可分享的房源。

处理结果

Contact Picker API 会返回一个联系人数组,每个联系人包含一个所请求属性的数组。如果联系人没有所请求属性的数据,或者用户选择不分享特定属性,则 API 会返回一个空数组。(我将在用户控制部分中介绍用户如何选择属性。)

例如,如果某个网站请求 nameemailtel,而用户选择的单个联系人在“姓名”字段中包含数据,提供了两个电话号码,但没有电子邮件地址,则返回的响应将为:

[{
  "email": [],
  "name": ["Queen O'Hearts"],
  "tel": ["+1-206-555-1000", "+1-206-555-1111"]
}]

安全与权限

Chrome 团队根据控制对强大的 Web 平台功能的访问权限中定义的核心原则(包括用户控制、透明度和人机工程学),设计并实现了 Contact Picker API。下面将逐一说明。

用户控制

通过选择器访问用户联系人,并且只能在安全的顶级浏览上下文中通过用户手势调用选择器。 这样可确保网站不会在页面加载时显示选择器,也不会在没有任何上下文的情况下随机显示选择器。

屏幕截图,用户可以选择要分享哪些房源。
用户可以选择不共享某些房源。在此屏幕截图中,用户已取消选中“电话号码”按钮。即使网站要求提供电话号码,系统也不会将电话号码分享给该网站。

没有用于批量选择所有联系人的选项,这样可鼓励用户仅选择需要与特定网站分享的联系人。用户还可以通过切换选择器顶部的属性按钮来控制与网站共享哪些属性。

透明度

为了明确要分享哪些联系信息,选择器始终会显示联系人的姓名和图标,以及网站已请求的所有属性。例如,如果网站请求 nameemailtel,这三个属性都会显示在选择器中。或者,如果网站仅请求 tel,选择器将仅显示名称和电话号码。

请求所有媒体资源的网站的选择器屏幕截图。
选择器,请求 nameemailtel 的网站,选择了一个联系人。
仅请求电话号码的网站的选择器屏幕截图。
选择器,网站仅请求 tel,已选择一个联系人。
长按联系人时选择器的屏幕截图。
长按联系人后的结果。

长按某个联系人会显示如果选择该联系人,系统将分享的所有信息。(请参阅“Cheshire Cat”联系人图片。)

无权限持久性

对联系人信息的访问是按需进行的,不会持久保留。每次网站想要访问时,都必须通过用户手势调用 navigator.contacts.select(),并且用户必须单独选择要与网站分享的联系人。

反馈

Chrome 团队希望了解您使用联系人选择器 API 的体验。

实现存在问题?

您是否发现 Chrome 的实现存在 bug?还是实现与规范不同?

  • 请访问 https://new.crbug.com 提交 bug。请务必尽可能详细地说明问题,提供重现 bug 的简单说明,并将组件设置为 Blink>Contacts

打算使用 API?

您是否打算使用 Contact Picker API?您的公开支持有助于 Chrome 团队确定功能的优先级,并向其他浏览器供应商展示支持这些功能的重要性。

实用链接

谢谢

特别感谢 Finnur Thorarinsson 和 Rayan Kanso,他们正在实现该功能;还要感谢 Peter Beverloo,我毫不避讳地窃取了他的代码并对其进行了重构以用于演示。

附注:我的联系人选择器中的名称是《爱丽丝梦游仙境》中的角色。