Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
147 views
in Technique[技术] by (71.8m points)

android - Sorted list of contacts having duplicates ,why?

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??

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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, " phone: " + phone);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...