Cordova/Ionic按手机号避免重复保存联系人问题求助
搞定重复保存联系人的问题!
我看了你代码里的问题,核心就是联系人查询逻辑没写对,导致明明通讯录里有相同手机号的人,代码还是一个劲地重复创建,甚至搞出103条重复的。我帮你把问题拆解开,再给你修复好的代码:
为啥会重复保存?
- 过滤条件不匹配:你用原始的
xs(可能带符号、空格)去查联系人,但你存的时候是转成纯数字的pn,这就导致查不到已存在的联系人,每次都触发保存。 - 查询字段限制错了:你设置
options.desiredFields = [navigator.contacts.fieldType.id],这会让查询结果只返回联系人ID,根本拿不到手机号信息,自然没法判断是不是同一个人。 - 定时器重复创建:每次点击按钮都会新建一个
setInterval,点几次就有几个定时任务同时跑,重复拉数据重复存,这就雪上加霜了。
修复后的完整代码
我把这些问题都修正了,还优化了变量传递,避免全局变量坑:
var app = { initialize: function() { document.addEventListener('deviceready', this.onDeviceReady.bind(this), false); this.syncInterval = null; // 存定时器ID,防止重复创建 }, onDeviceReady: function() { this.receivedEvent('deviceready'); document.getElementById("call").addEventListener("click", ayam); cordova.plugins.backgroundMode.enable(); }, receivedEvent: function(id) { var parentElement = document.getElementById(id); var listeningElement = parentElement.querySelector('.listening'); var receivedElement = parentElement.querySelector('.received'); listeningElement.setAttribute('style', 'display:none;'); receivedElement.setAttribute('style', 'display:block;'); console.log('Received Event: ' + id); } }; app.initialize(); function dialogAlert() { var message = "Sync Android Contact has been activated!"; var title = "Info"; var buttonName = "Close"; navigator.notification.alert(message, alertCallback, title, buttonName); function alertCallback() { console.log("Alert is Dismissed!"); } } function ayam() { var apiUrl = $(".aba").val(); if(apiUrl.length > 3) { // 先清掉旧定时器,避免多个任务同时跑 if(app.syncInterval) { clearInterval(app.syncInterval); } // 新建定时任务,把apiUrl传进去 app.syncInterval = setInterval(function(){ kambing(apiUrl); }, 5000); dialogAlert(); } else { alert("Write your API Url !"); } } function kambing(url){ $.ajax({ type : "GET", url : url + "/save", dataType : 'html', success: function(response){ var hp = response, anu = hp.split(","); anu.forEach(function(v){ save_contact(v, url); // 把url传给保存函数 }) }, error : function() { alert("Failed to fetch url"); } }); } function save_contact(xs, url){ var pn = xs.replace(/\D/g,''); if(pn.length > 3) { var options = new ContactFindOptions(); options.filter = pn; // 用纯数字手机号当过滤条件 options.multiple = true; options.hasPhoneNumber = true; var fields = [navigator.contacts.fieldType.phoneNumbers]; navigator.contacts.find(fields, function(contacts) { // 检查有没有匹配的手机号(转成纯数字再对比) var contactExists = contacts.some(function(contact) { return contact.phoneNumbers.some(function(phone) { var contactPhone = phone.value.replace(/\D/g,''); return contactPhone === pn; }); }); if(!contactExists) { var myContact = navigator.contacts.create({"displayName": xs}); var name = new ContactName(); name.givenName = xs; myContact.name = name; var phoneNumbers = []; phoneNumbers[0] = new ContactField('mobile', pn, true); myContact.phoneNumbers = phoneNumbers; myContact.note = "Hello"; myContact.save(function(contact) { console.log("Contact saved successfully:", contact); $.ajax({ url : url, type : 'POST', dataType: 'html', data : {wdyw:0, title:content, isanony:isanony, category:category, url:url}, success : function(result){ $('[name="content"]').val('Pertanyaan anda telah terkirim :)'); setTimeout(function(){ $('[name="content"]').val(''); },500); } }); }, function(contactError) { console.error("Error saving contact:", contactError); }); } }, function(contactError) { console.error("Error finding contacts:", contactError); }, options); } }
重点改了啥?
- 定时器防重复:加了
app.syncInterval来管理定时器,每次点击先清旧的,再建新的,不会出现多个定时任务同时跑的情况。 - 查询条件精准匹配:用纯数字的
pn去查,而且判断的时候把联系人的手机号也转成纯数字对比,确保一模一样才认定为已存在。 - 去掉不必要的字段限制:删掉了
options.desiredFields,这样能拿到联系人的手机号信息,才能做对比。 - 变量传递更合理:把
url作为参数传递,不用依赖全局变量,减少莫名其妙的bug。
这样改完之后,就只会在通讯录里没有对应手机号联系人的时候才保存,不会再出现一堆重复的了。
内容的提问来源于stack exchange,提问作者Rubi Jihantoro




