Android: Contact list has duplicate names
Asked Answered
C

4

6

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.

Callida answered 8/12, 2015 at 7:23 Comment(1)
Please post full code adapterQuietism
B
5

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.

Blackout answered 23/12, 2015 at 13:40 Comment(1)
From from Uri we cannot retrieve the email address.Is their any way to get the name,phone and email in one query.Jugulate
M
7

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"

Moratorium answered 11/6, 2017 at 15:40 Comment(1)
That is great @Zain, I am able to filter the google contacts now, do you know how to filter on a specific google account if there is more than one google account on the device?Elizabetelizabeth
B
5

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.

Blackout answered 23/12, 2015 at 13:40 Comment(1)
From from Uri we cannot retrieve the email address.Is their any way to get the name,phone and email in one query.Jugulate
M
0

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

Mayda answered 30/3, 2016 at 9:30 Comment(0)
H
0

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

Harrumph answered 1/3, 2019 at 20:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.