【问题标题】:Android get phone contacts and remove duplicatesAndroid获取电话联系人并删除重复项
【发布时间】:2015-08-18 09:48:37
【问题描述】:

我遇到了与联系人有关的问题。我得到了电话联系人并将它们存储在我的列表对象中。这是它的代码

  Uri uri = ContactsContract.Data.CONTENT_URI;

    String[] projection = {
            ContactsContract.Data.CONTACT_ID,
            ContactsContract.Data.DISPLAY_NAME,
            ContactsContract.Data.PHOTO_ID,
            ContactsContract.Data.DATA1
    };

    Cursor phones = getContentResolver().query(
            uri, projection, ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND " + ContactsContract.Data.DATA1 + "!=''", null, null);


    if (phones.moveToFirst()) {

        do {
            long ID =   phones.getLong(phones.getColumnIndex(projection[0]));
            String DisplayName  =   phones.getString(phones.getColumnIndex(projection[1]));
            String photoID =    phones.getString(phones.getColumnIndex(projection[2]));
            String Key =    phones.getString(phones.getColumnIndex(projection[3]));
            String photoURI = "null";

            if(Key != null && Key.toString().trim().length() > 0 && (Key.startsWith("0") || Key.startsWith("+"))){
                if (photoID != null) {
                    photoURI=String.valueOf(ID);;
                    //Console.WriteLine("*************************************> id="+ID+" uri="+photoURI.ToString());
                }
                ContactBean contactModel=new ContactBean(DisplayName,Key,photoID);

            list.add(contactModel);
            } else {
                // No number!!
            }
        } while (phones.moveToNext());
    }

我正在根据我的要求删除所有联系人和电子邮件联系人。我的问题是我得到了所有的联系人,包括重复的联系人。如果我有一个联系人以相同的姓名和号码保存了 3 次,它将获取所有三个联系人。我不想要这个。有什么办法可以避免这种情况。 getContactResolver 查询中的任何内容,否则我必须删除列表的重复项。有什么解决方案或建议吗?

【问题讨论】:

标签: java android android-contacts


【解决方案1】:

你可以试试这个:

        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC ");
        String lastnumber = "0";

        if (cur.getCount() > 0)
        {
            while (cur.moveToNext())
            {
                String number = null;
                String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
                {
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]
                    { id }, null);
                    while (pCur.moveToNext())
                    {
                        number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        Log.e("lastnumber ", lastnumber);
                        Log.e("number", number);

                        if (number.equals(lastnumber))
                        {

                        }
                        else
                        {
                            lastnumber = number;

                            Log.e("lastnumber ", lastnumber);
                            int type = pCur.getInt(pCur.getColumnIndex(Phone.TYPE));
                            switch (type)
                            {
                                case Phone.TYPE_HOME:
                                    Log.e("Not Inserted", "Not inserted");
                                    break;
                                case Phone.TYPE_MOBILE:

                                    databaseHandler.insertContact(id, name, lastnumber, 0);
                                    break;
                                case Phone.TYPE_WORK:
                                    Log.e("Not Inserted", "Not inserted");
                                    break;
                            }

                        }

                    }
                    pCur.close();
                }

            }
        }

这里我先在 sqlite 数据库中插入数据,然后按名称编写选择查询。

希望对你有帮助

【讨论】:

  • 我测试了它,但我仍然得到重复的联系人。
【解决方案2】:

使用PhoneNumberUtils.compare(a, b) 过滤掉重复的数字

val contacts = ArrayList<MyContact>()
val uniqueMobilePhones = ArrayList<String>()
                while (cursorPhones.moveToNext()) {
                    val displayName = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
                    val number = cursorPhones.getString(cursorPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                    val convertedNumber = convert(telman, number)
                    var duplicate = false
                    uniqueMobilePhones.forEach { addedNumber ->
                        if (PhoneNumberUtils.compare(addedNumber, number)) {
                            duplicate = true
                        }
                    }

                    if (!duplicate) {
                        uniqueMobilePhones.add(number)
                        contacts.add(MyContact(displayName, number, convertedNumber.replace(Regex("[ -+()]"), "")))
                    }
                }

【讨论】:

  • 上述代码中的“val”是什么?如何在 Android java 编码中使用它?
  • Kotlin val 是只读参数,以后不能重新分配。 val 与 java 中的 final 修饰符相同
【解决方案3】:
 String lastnumber = "0";
    ContentResolver cr = getContentResolver();
    Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, Constants.PROJECTION, null, null, null);
    if (cursor != null) {
        try {
            final int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            final int numberIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            String name, number;
            while (cursor.moveToNext()) {
                name = cursor.getString(nameIndex);
                number = cursor.getString(numberIndex).trim();
                number = number.replaceAll("\\s", "");
                if (number.equals(lastnumber)) {

                } else {
                    lastnumber = number;
                    Contact contact = new Contact();
                    contact.name = name;
                    contact.phone = number;
                    mContactList.add(contact);
                    if (adapter != null)
                        adapter.notifyDataSetChanged();
                    System.out.println("ContactFragment.readContact ==>" + name);
                }
            }
        } finally {
            cursor.close();
        }
    }

【讨论】:

    【解决方案4】:

    这里的代码是在您的联系人列表中查找重复号码以及该号码在您的联系人列表中出现的频率

    public ArrayList<ContactToDelete> findDuplicates(ArrayList<Contact> listContainingDuplicates) {
        ArrayList<Contact> duplicatesOrganised = new ArrayList();
        ArrayList<ContactToDelete> setToReturn = new ArrayList();
    
        // Collections.sort(listContainingDuplicates);
    
        Collections.sort(listContainingDuplicates, new Comparator<Contact>() {
            public int compare(Contact obj1, Contact obj2) {
                // ## Ascending order
                return obj1.getPhoneNumber().compareToIgnoreCase(obj2.getPhoneNumber()); // To compare string values
                // return Integer.valueOf(obj1.empId).compareTo(Integer.valueOf(obj2.empId)); // To compare integer values
    
                // ## Descending order
                // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values
                // return Integer.valueOf(obj2.empId).compareTo(Integer.valueOf(obj1.empId)); // To compare integer values
            }
        });
    
        int ii, size = listContainingDuplicates.size();
    
        //Orders all the duplicates together along with the unique(non-duplicate)
        for (ii = 0; ii < size; ii++) {
            if (ii + 1 == size) {
                duplicatesOrganised.add(listContainingDuplicates.get(ii));
                Log.i("DuplicateOrdered: ", listContainingDuplicates.get(ii).getPhoneNumber() + " " + listContainingDuplicates.get(ii).getName());
            } else if (listContainingDuplicates.get(ii).getPhoneNumber().equals(listContainingDuplicates.get(ii + 1).getPhoneNumber())) {
                duplicatesOrganised.add(listContainingDuplicates.get(ii));
                Log.i("DuplicateOrdered: ", listContainingDuplicates.get(ii).getPhoneNumber() + " " + listContainingDuplicates.get(ii).getName());
            } else {
                duplicatesOrganised.add(listContainingDuplicates.get(ii));
                Log.i("DuplicateOrdered: ", listContainingDuplicates.get(ii).getPhoneNumber() + " " + listContainingDuplicates.get(ii).getName());
            }
        }
        int firstcome = 0;
        int start = 0;
        boolean present = false;
        boolean duplicatefond = false;
        int startsetToReturn = 0;
        if (!duplicatesOrganised.isEmpty() &&
                duplicatesOrganised.size() > 1 &&
                !duplicatesOrganised.get(0).getPhoneNumber().equals(duplicatesOrganised.get(1).getPhoneNumber())) {
            start = 1;
        }
    
        for (int i = 0; i < duplicatesOrganised.size(); i++) {
            String currentNumber = duplicatesOrganised.get(i).getPhoneNumber();
            if(setToReturn.size()>0){
                for (int j = 0; j <setToReturn.size() ; j++) {
                    if(setToReturn.get(j).getNumber().equals(currentNumber)){
                        present = true;
                    }
                }
            }
            int flag = 0;
            if(!present) {
                for (int j = i+1; j < duplicatesOrganised.size(); j++) {
                    if (duplicatesOrganised.get(j).getPhoneNumber().equals(currentNumber)) {
                        duplicatefond = true;
                        if (flag == 0) {
                                flag++;
                                setToReturn.add(new ContactToDelete(duplicatesOrganised.get(i).getPhoneNumber(), duplicatesOrganised.get(i).getName(), flag));
    
                        } else
                            {
                                flag++;
                                setToReturn.get(startsetToReturn).setRepeatValue(flag);
    
                        }
    
                    }
                }
                if(duplicatefond) {
                    startsetToReturn++;
                    duplicatefond = false;
                }
            }
            firstcome = 0;
            present = false;
        }
        startsetToReturn =0;
        Log.e("setToReturn", setToReturn.toString());
        return setToReturn;
    }
    

    我使用的两个模型类,一个用于获取完整的联系人列表,另一个用于获取重复号码

    没有1个模型类

    public class ContactToDelete {
        private String number;
        private String name;
        private int repeatValue;
        private String contactID;
    
        public ContactToDelete(String number, String name, int repeatValue, String contactID) {
            this.number = number;
            this.name = name;
            this.repeatValue = repeatValue;
            this.contactID = contactID;
        }
    
        public ContactToDelete() {
        }
    
        public ContactToDelete(String number, String name, int repeatValue) {
            this.number = number;
            this.name = name;
            this.repeatValue = repeatValue;
        }
    
        public String getContactID() {
            return contactID;
        }
    
        public void setContactID(String contactID) {
            this.contactID = contactID;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getRepeatValue() {
            return repeatValue;
        }
    
        public void setRepeatValue(int repeatValue) {
            this.repeatValue = repeatValue;
        }
    }
    

    No 2 模型类

    public class Contact {
        public String name;
        public String phoneNumber;
    
        public Contact(String name, String phoneNumber, String contactID) {
            this.name = name;
            this.phoneNumber = phoneNumber;
            this.contactID = contactID;
        }
        public String getContactID() {
            return contactID;
        }
    
        public void setContactID(String contactID) {
            this.contactID = contactID;
        }
        public String contactID;
        public Contact() {
        }
        public Contact(String name, String phoneNumber) {
            this.name = name;
            this.phoneNumber = phoneNumber;
        }
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPhoneNumber() {
            return phoneNumber;
        }
    
        public void setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }
    }
    

    【讨论】:

      【解决方案5】:

      使用内容提供程序/游标加载器拥有多个联系人是显而易见的,因为我们正在查询原始联系人列表。我删除重复项的方法是覆盖 hashcode 和 equals 方法。下面是我的代码,它将避免将多个联系人添加到列表中。

      import android.os.Parcel;
      import android.os.Parcelable;
      import android.text.TextUtils;
      

      模型类包含以下字段。您可以根据需要进行修改。

      private String name;
      private String number;
      private boolean isSelected;
      

      现在覆盖模型类中的 hashcode 和 equals 方法。

      @Override
      public boolean equals(Object v) {
          boolean retVal = false;
          if (v instanceof SelectableContact){
              SelectableContact ptr = (SelectableContact) v;
              if(ptr != null) {
                  //We can add some regexpressions to ignore special characters or spaces but
                  // this consumes a lot of memory and slows down the contact loading.
                  if(!TextUtils.isEmpty(ptr.number) && !TextUtils.isEmpty(this.number) && ptr.number.equalsIgnoreCase(this.number)) {
                      retVal = true;
                  }//if
              }
          }
      
          return retVal;
      }
      
      @Override
      public int hashCode() {
          int hash = 7;
          hash = 17 * hash + (this.number != null ? this.number.hashCode() : 0);
          return hash;
      }
      

      现在可以走了。如果列表项的内容相同,则在添加列表时声明拒绝。 看看下面的例子。让我的模型类是联系人。

      public class Contact implements implements Parcelable {
      
      }
      

      一旦您从 contentProvider 或 ContactCursor 加载器获取联系人, 执行此操作。

      List<Contact> contactList = new ArraList<>;
      Contact contact = new Contact();
      if(!contactList.contains(contact)) {
          //add contact to list.
      }else {
          //remove contact from list.
      }
      

      hashcode 和 equals 方法会在添加之前比较列表项的内容。如果存在相同的内容,它将被删除。

      可以走了。

      有关详细信息,请参阅 Why do I need to override the equals and hashCode methods in Java?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-30
        • 2021-02-08
        • 2011-07-16
        • 1970-01-01
        • 2013-05-19
        相关资源
        最近更新 更多