Binil Surendran
Binil Surendran

Reputation: 2564

Android: Contact list has duplicate names

I have a contact list in a sort order. But in my contact list the name is duplicating with same number. I think the issue is because of the contact list sync with different account.

I check with Hash map. But when I using hash map the result is not sorted with name .

private static final String[] PROJECTION = new String[] {
    ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.CommonDataKinds.Phone.NUMBER
};

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION,
  null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE NOCASE ASC");

if (cursor != null) {
    try {
        int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        String nameContact = cursor.getString(nameIndex);
    finally {
        cursor.close();
    }
}

Adapter

holder.name.setText(itemListPogo.get(position).getItemName());

Can anyone please help to avoid the duplication in name.

Upvotes: 6

Views: 5197

Answers (4)

Tsuharesu
Tsuharesu

Reputation: 1169

You can search for the aggregated Contact instead of all RawContacts. This will give you only 1 contact with the given name (like in the Contacts app). Example (changing your code):

private static final String[] PROJECTION = new String[] {
    ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY, // Honeycomb+ should use this
    ContactsContract.CommonDataKinds.Phone.NUMBER
};

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(
    ContactsContract.Contacts.CONTENT_URI, 
    PROJECTION, 
    null, 
    null, 
    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " COLLATE NOCASE ASC");

if (cursor != null) {
    try {
        int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY);
        String nameContact = cursor.getString(nameIndex);
    finally {
        cursor.close();
    }
}

Source: https://developer.android.com/reference/android/provider/ContactsContract.Contacts.html

Upvotes: 0

PhiNM
PhiNM

Reputation: 31

I think the issue is because of the contact list sync with different account.

Yes, your contact list sync many account. You should filter contact with Account type : ContactsContract.CommonDataKinds.Phone.ACCOUNT_TYPE_AND_DATA_SET.
Account you can research in : https://developer.android.com/reference/android/accounts/AccountManager.html

Upvotes: 0

Zain Ul Abdin
Zain Ul Abdin

Reputation: 199

You're seeing duplicate contacts because they belong to different accounts. i.e. Same number can show up 3 times if it is synced with Facebook, WhatsApp, and Google account. You can find more information here Android Account Manager

This is how you can use column ContactsContract.RawContacts.ACCOUNT_TYPE to filter and retrieve contacts associated with a single account only.

String[] projection = new String[] {
                    ContactsContract.RawContacts._ID,
                    ContactsContract.RawContacts.ACCOUNT_TYPE,
                    ContactsContract.Contacts.DISPLAY_NAME,
                    ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
                    ContactsContract.CommonDataKinds.Phone.NUMBER,
                    ContactsContract.CommonDataKinds.Photo.CONTACT_ID };


            String selectionFields =  ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?";
            String[] selectionArgs = new String[]{"com.google"};

            Cursor cursor =  getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    projection,
                    selectionFields,
                    selectionArgs,
                    ContactsContract.Contacts.DISPLAY_NAME
            );

In this code, only contacts that are associated with Google Account are selected. Similarly, if you want to get list of WhatsApp Contacts only you can replace "com.google" with "com.whatsapp"

Upvotes: 7

Amol Patil
Amol Patil

Reputation: 1005

I will recommend you to use where my searching ends, it will give you fastest result.

public static List<ContactDTO> getPhone(Context context) {
    List<ContactDTO> contactList = new ArrayList<ContactDTO>();
    ContentResolver cr = context.getContentResolver(); 
    String[] PROJECTION = new String[] { 
        ContactsContract.RawContacts._ID, 
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.PHOTO_URI,
        ContactsContract.CommonDataKinds.Phone.NUMBER,
        ContactsContract.CommonDataKinds.Photo.CONTACT_ID };

    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String filter = ""+ ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and " + Phone.TYPE +"=" + Phone.TYPE_MOBILE;     
    String order = ContactsContract.Contacts.DISPLAY_NAME + " ASC";// LIMIT " + limit + " offset " + lastId + "";

    Cursor phoneCur = cr.query(uri, PROJECTION, filter, null, order);
    while(phoneCur.moveToNext()) {
        ContactDTO dto = new ContactDTO();
        dto.setName("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
        dto.setMobileNo("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
        dto.setPhotoUrl("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI)));
        dto.setContactId("" + phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Photo.CONTACT_ID)));
        contactList.add(dto);
    }
    phoneCur.close();

    return contactList;
} 

where ContactDTO is Simple POJO class.

Upvotes: 5

Related Questions