Skip to content

Cordova - 联系人

cordova-plugin-contacts 插件提供了访问设备联系人数据库的能力。你可以使用它来查找、创建和删除联系人。注意:此插件需要用户授予访问联系人的权限。

使用 Cordova CLI 安装插件:

cordova plugin add cordova-plugin-contacts

添加插件后,为你正在目标的平台重新构建项目(例如 cordova build android)。

在 www/index.html 中,添加用于联系人操作的按钮以及一个 div 来显示结果:

<body>
<h1>联系人演示</h1>
<button id="createContactBtn">添加联系人</button>
<button id="findContactBtn">查找联系人</button>
<button id="deleteContactBtn">删除 'Test User'</button>
<div id="contactResults"></div>
<script src="cordova.js"></script>
<script src="js/index.js"></script>
</body>

在 www/js/index.js 中,在 onDeviceReady 内部,设置事件监听器。所有 navigator.contacts API 调用都必须在 deviceready 触发后进行。

document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
console.log('设备已就绪。联系人 API 可用。');
document.getElementById('createContactBtn').addEventListener('click', createContact);
document.getElementById('findContactBtn').addEventListener('click', findContacts);
document.getElementById('deleteContactBtn').addEventListener('click', deleteTestContact);
// 如有需要,显式检查权限是一种良好的实践,
// 尽管插件通常会处理初始提示。
// 对于高级场景,请参阅权限插件。
}
const displayResults = (message) => {
document.getElementById('contactResults').innerHTML = `<p>${message}</p>`;
console.log(message);
};
const displayError = (error) => {
let errorMessage = '操作失败。';
if (error && error.code) {
switch (error.code) {
case ContactError.UNKNOWN_ERROR: errorMessage = '未知错误。'; break;
case ContactError.INVALID_ARGUMENT_ERROR: errorMessage = '无效参数。'; break;
case ContactError.TIMEOUT_ERROR: errorMessage = '超时错误。'; break;
case ContactError.PENDING_OPERATION_ERROR: errorMessage = '待处理操作错误。'; break;
case ContactError.IO_ERROR: errorMessage = 'I/O 错误。'; break;
case ContactError.NOT_SUPPORTED_ERROR: errorMessage = '不支持错误。'; break;
case ContactError.PERMISSION_DENIED_ERROR: errorMessage = '权限被拒绝。'; break;
default: errorMessage = `错误代码:${error.code}`;
}
}
document.getElementById('contactResults').innerHTML = `<p style="color: red;">错误:${errorMessage}</p>`;
console.error('联系人错误:', errorMessage, error);
};
// 3A - 创建联系人
async function createContact() {
try {
const contact = navigator.contacts.create();
contact.displayName = "Test User";
contact.nickname = "Tester"; // 默认与 displayName 相同
const name = new ContactName();
name.givenName = "Test";
name.familyName = "User";
contact.name = name;
const phoneNumbers = [];
phoneNumbers[0] = new ContactField('mobile', '123-456-7890', true); // 首选号码
contact.phoneNumbers = phoneNumbers;
await new Promise((resolve, reject) => {
contact.save(() => resolve(), (err) => reject(err));
});
displayResults("联系人 'Test User' 保存成功!");
} catch (err) {
displayError(err);
}
}
// 3B - 查找联系人
async function findContacts() {
try {
const options = new ContactFindOptions();
options.filter = ""; // 空过滤器表示查找所有,或指定搜索词,例如 "Test"
options.multiple = true;
// options.desiredFields = [navigator.contacts.fieldType.id, navigator.contacts.fieldType.displayName, navigator.contacts.fieldType.name]; // 如有需要,指定字段
const fields = ["displayName", "name", "phoneNumbers"]; // 用于搜索和检索的字段
const contactsFound = await new Promise((resolve, reject) => {
navigator.contacts.find(fields, (contacts) => resolve(contacts), (err) => reject(err), options);
});
if (contactsFound.length === 0) {
displayResults("未找到联系人。");
return;
}
let html = '<h3>找到的联系人:</h3><ul>';
contactsFound.forEach(contact => {
html += `<li>${contact.displayName || (contact.name ? contact.name.formatted : 'N/A')}`;
if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
html += ` (${contact.phoneNumbers[0].value})`;
}
html += `</li>`;
});
html += '</ul>';
document.getElementById('contactResults').innerHTML = html;
console.log('找到的联系人:', contactsFound);
} catch (err) {
displayError(err);
}
}
// 3C - 删除特定联系人
async function deleteTestContact() {
try {
const options = new ContactFindOptions();
options.filter = "Test User"; // 要删除的联系人名称
options.multiple = false; // 我们期望找到一个或依赖于第一个匹配项
const fields = ["displayName"];
const contactsFound = await new Promise((resolve, reject) => {
navigator.contacts.find(fields, (contacts) => resolve(contacts), (err) => reject(err), options);
});
if (!contactsFound || contactsFound.length === 0) {
displayResults("未找到要删除的联系人 'Test User'。");
return;
}
const contactToDelete = contactsFound[0];
await new Promise((resolve, reject) => {
contactToDelete.remove(() => resolve(), (err) => reject(err));
});
displayResults(`联系人 '${contactToDelete.displayName}' 删除成功。`);
} catch (err) {
displayError(err);
}
}
  • 权限:访问联系人是一项敏感操作。插件通常会触发操作系统的权限请求对话框。你的应用程序应处理权限被拒绝的情况。ContactError.PERMISSION_DENIED_ERROR 代码可以指示这种情况。考虑使用专用的权限插件来更精细地控制权限请求和状态检查。
  • 异步操作:所有联系人操作(保存、查找、删除)都是异步的。上面的示例使用了 async/await 结合 Promises 来编写更清晰的代码。原始的插件 API 使用成功和错误回调。
  • 错误处理:务必提供错误回调函数或使用 try/catch 结合 Promises 来处理潜在问题,例如权限被拒绝、I/O 错误或无效参数。
  • ContactFindOptions:使用 filter 搜索特定联系人。空字符串 "" 通常会尝试获取所有联系人(如果联系人很多可能会很慢)。multiple: true 允许返回多个匹配项。
  • 数据结构:联系人可能包含复杂数据(多个电话号码、电子邮件、地址)。熟悉 ContactName、ContactField、ContactAddress 等对象。
  • 平台差异:虽然 Cordova 致力于跨平台一致性,但在不同操作系统上处理联系人或可用数据的方式可能存在细微差异。

管理联系人在以下方面很有用:

  • 用于查找朋友的社交网络应用程序。
  • 用于发起电话或消息的通信应用程序。
  • 用于管理客户信息的 CRM 或商业应用程序。
  • 允许用户选择联系人进行分享或其他交互的应用程序。

有关更多详细信息,请查阅 Cordova Contacts Plugin documentation 的官方文档。