You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Cordova/Ionic按手机号避免重复保存联系人问题求助

搞定重复保存联系人的问题!

我看了你代码里的问题,核心就是联系人查询逻辑没写对,导致明明通讯录里有相同手机号的人,代码还是一个劲地重复创建,甚至搞出103条重复的。我帮你把问题拆解开,再给你修复好的代码:

为啥会重复保存?

  1. 过滤条件不匹配:你用原始的xs(可能带符号、空格)去查联系人,但你存的时候是转成纯数字的pn,这就导致查不到已存在的联系人,每次都触发保存。
  2. 查询字段限制错了:你设置options.desiredFields = [navigator.contacts.fieldType.id],这会让查询结果只返回联系人ID,根本拿不到手机号信息,自然没法判断是不是同一个人。
  3. 定时器重复创建:每次点击按钮都会新建一个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);
  }
}

重点改了啥?

  1. 定时器防重复:加了app.syncInterval来管理定时器,每次点击先清旧的,再建新的,不会出现多个定时任务同时跑的情况。
  2. 查询条件精准匹配:用纯数字的pn去查,而且判断的时候把联系人的手机号也转成纯数字对比,确保一模一样才认定为已存在。
  3. 去掉不必要的字段限制:删掉了options.desiredFields,这样能拿到联系人的手机号信息,才能做对比。
  4. 变量传递更合理:把url作为参数传递,不用依赖全局变量,减少莫名其妙的bug。

这样改完之后,就只会在通讯录里没有对应手机号联系人的时候才保存,不会再出现一堆重复的了。

内容的提问来源于stack exchange,提问作者Rubi Jihantoro

火山引擎 最新活动