Sorted list of contacts having duplicates ,why?
Asked Answered
B

7

5

I have sorted and listed my phone contacts in to an arraylist but ,i got many duplicates of same contact names in the list .How this happens? how to avoid this?

This is what i have tried,

  cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null,
                "(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC");

  while (cursor.moveToNext()) {

        try {

            name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            phonenumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            contact_names_list.add(name);
            phone_num_list.add(phonenumber);


        } catch (Exception e) {
            e.printStackTrace();
        }

can anyone help??

Bibliography answered 13/12, 2017 at 5:42 Comment(4)
you can use HASHSETLightface
any example please?Bibliography
Are the contacts in more than one group? For example, on the SIM and in Google Contacts.Tennison
yeah some contacts are in one group , but not all contacts , here i am getting more than 2 duplicates of each contact name.Bibliography
Q
6

No one here seems to answer your question.

The reason you're seeing duplicate contacts is that you're querying for phones not contacts.

In Android there are 3 main tables:

  1. Contacts table - has one item per contact
  2. RawContacts table - has one item per-contact per-account (such as Google, Outlook, Whatsapp, etc.) - multiple RawContacts are linked to a single Contact
  3. Data table - has one item per detail (name, email, phone, address, etc.) - each data item is linked to a single RawContact, and multiple Data rows are linked to each RawContact.

You're querying on CommonDataKinds.Phone.CONTENT_URI which is a part of the Data table, so if a contact has more then one phone, and/or it has the same phone from multiple sources (e.g. Google and Whatsapp) you'll get the same phone with the same CONTACT_ID more then once.

The solution would be, to use a HashMap (rather then a HashSet), where the key is CONTACT_ID, so you can display multiple phones per contact:

String[] projection = new String[] { CommonDataKinds.Phone.CONTACT_ID, CommonDataKinds.Phone.DISPLAY_NAME, CommonDataKinds.Phone.NUMBER };
Cursor cursor = getContentResolver().query(CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);

HashMap<Long, Contact> contacts = new HashMap<>();

while (cursor.moveToNext()) {
    long id = cursor.getLong(0);
    String name = cursor.getString(1);
    String phone = cursor.getString(2);

    Contact c = contacts.get(id);
    if (c == null) {
        // newly found contact, add to Map
        c = new Contact();
        c.name = name;
        contacts.put(id, c);
    }

    // add phone to contact class
    c.phones.add(phone);
}
cursor.close();


// simple class to store multiple phones per contact
private class Contact {
    public String name;
    // use can use a HashSet here to avoid duplicate phones per contact
    public List<String> phones = new ArrayList<>(); 
}

If you want to sort your HashMap by name:

List<Contact> values = new ArrayList<>(contacts.values());
Collections.sort(values, new Comparator<Contact> {
    public int compare(Contact a, Contact b) {
        return a.name.compareTo(b.name);
    }
});

// iterate the sorted list, per contact:
for (Contact contact : values) {
    Log.i(TAG, "contact " + contact.name + ": ");
    // iterate the list of phones within each contact:
    for (String phone : contact.phones) {
        Log.i(TAG, "\t phone: " + phone);
    }
}
Quaker answered 13/12, 2017 at 8:13 Comment(5)
You have done a great job , this one is the perfect solution to my problem .Thanks for the supportBibliography
How can i get a sorted list, i have tried treemap but it is not properly sortedBibliography
you can get just the values, as an ArrayList, from the HashMap, and then sort that ArrayList, see my updateQuaker
hai when i sort like this, how can i get phone numbers corresponding to each contacts in correct order ?Bibliography
:can you help me?Bibliography
L
3

You can try with HashSet.

public class HashSet extends AbstractSet implements Set, Cloneable, Serializable

  • Duplicate values are not allowed.

Code Structure

 HashSet<String> hashSET = new HashSet<String>();
        hashSET.add("AA");
        hashSET.add("BB");
        hashSET.add("CC");
        hashSET.add("AA"); // Adding duplicate elements

Then

Iterator<String> j = hashSET.iterator();
        while (j.hasNext())
            System.out.println(j.next()); // Will print "AA" once.
    }

Now SORT your Hashset Values using TreeSet.

TreeSet implements the SortedSet interface so duplicate values are not allowed.

 TreeSet<String> _treeSET= new TreeSet<String>(hashSET);
Lightface answered 13/12, 2017 at 5:55 Comment(8)
Thank you , but can you explain how this happen? i mean the duplicate values ??Bibliography
@Gibs No coming from SIM and MOBILE. (Google contacts also)Lightface
@Gibs Solved this yet?Lightface
Thank you it works ,but i lost the sorted order of the listBibliography
Now i have an unsorted list of contacts ,so i couldn't identify the contact number for each contactBibliography
@Gibs use TreeSetLightface
Ok thank you i will try it , and i am accepting your answer because it solved the duplicate issue.Bibliography
Let us continue this discussion in chat.Bibliography
T
2

May be in your contacts having multiple groups, and that group will be a WhatsApp,Google etc..Go to your contacts and search that contact having whatsApp account. will showing double entry with different Group

you should use or change your ContactsBean , in your Bean use HashSet

Note: HashSet can avoid duplicate entry more

HashSet contains unique elements only,it can avoid same key element form HashSet

Example bean

public class ContactBean {
    private HashSet<String> number = new HashSet<String>(); 

    public void setNumber(String number) {
        if (number == null)
            return; 
        this.number.add(number.trim()); 
    }

    public HashSet<String> getNumber() {
        return this.number; 
    }
}

Simple Example

//Creating HashSet and adding elements  
  
  HashSet<String> hashSet=new HashSet<String>();  
  hashSet.add("Dhruv");  
  hashSet.add("Akash");  
  hashSet.add("Dhruv");   //Avoiding this entry   
  hashSet.add("Nirmal");  

 //Traversing elements  
 
  Iterator<String> itr = hashSet.iterator();  
  while(itr.hasNext()){  
   System.out.println(itr.next());
} 
Tedi answered 13/12, 2017 at 5:56 Comment(0)
P
1

You can use HashSet for avoid duplication:-

HashSet<String> hset = 
               new HashSet<String>();

you can add like ArrayList in HashSet:-

hset.add(your_string);

OR

Convert your ArrayList to HashSet :-

Set<String> set = new HashSet<String>(your_arraylist_object);

HashSet avoid Duplicate Entry :)

Piecedyed answered 13/12, 2017 at 5:49 Comment(3)
Thank you for the answer, but my question is how to avoid the duplicates when sorting , any help?Bibliography
convert your arraylist into hashset after sorting :)Piecedyed
check updated answer that remove duplicate from arraylist :)Piecedyed
D
1

I don't know why are you getting duplicate items from contacts, maybe phone contacts already have duplicate values.You can check that in Contacts app.

You should always use set data structure wherever you want to avoid duplicate items. You can find the better explanation and example here.

Deviltry answered 13/12, 2017 at 6:0 Comment(0)
O
0

I think your duplication is because of Whatsapp contact interfering with contact . so you can use something like this

                      String lastPhoneName = "";
                     String lastPhoneNumber = "";

                    //IN YOUR CONTACT FETCHING WHILE LOOP , INSIDE TRY 
                   String contactName = c.getString(c
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phNumber = c
                            .getString(c
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                    if (!contactName.equalsIgnoreCase(lastPhoneName) && !phNumber.equalsIgnoreCase(lastPhoneNumber)) {

                        lastPhoneName = contactName;
                        lastPhoneNumber = phNumber;

                        ContactModel model = new ContactModel();
                        model.setContact_id(contactid);
                        model.setContact_name(contactName.replaceAll("\\s+", ""));
                        model.setContact_number(phNumber.replaceAll("\\D+", ""));


                        list_contact_model.add(model);

                    } 

this will check that previous number is same as old one than skip it . I hope You get your answer

Orren answered 13/12, 2017 at 6:10 Comment(0)
K
0

HashSet add items in key/value pair and also remove duplicate entry from item set.

List<String> phone_num_list= new ArrayList<>();
// add elements to phone_num_list, including duplicates
Set<String> hs = new HashSet<>();
hs.addAll(phone_num_list);
phone_num_list.clear();
phone_num_list.addAll(hs);

Happy coding!!

Kynan answered 13/12, 2017 at 6:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.