3

I am trying to display contacts in Recycler View everything is working fine but contacts are getting displayed twice or thrice.

Here is the Code

 RecyclerView recyclerView;
 List<Contacts> contactsList;
 ContactsAdapter adapter;

 public void getContactList() {
    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null,
            "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

        Contacts contacts = new Contacts(name, number);
        if (contactsList.contains(contacts)){
            cursor.moveToNext();
        }
        else {
            contactsList.add(contacts);
        }
        adapter = new ContactsAdapter(contactsList, getApplicationContext());
        recyclerView.setAdapter(adapter);

        adapter.notifyDataSetChanged();
    }
}

So, how can I solve this problem?

HARSH ASHRA
  • 176
  • 1
  • 4
  • 20
  • You are not clearing the list anywhere... Maybe the function happens more than once and the values are added to the list again and again? – Dan Baruch Nov 03 '20 at 09:57

5 Answers5

2

Pass only phoneNumber as a key and phoneName as a value You can use :

Map<String, String> map = new HashMap<>();
map.put("A", "1");
...
System.out.printf("Before: %s%n", map);

// Set in which we keep the existing values
Set<String> existing = new HashSet<>();
map = map.entrySet()
    .stream()
    .filter(entry -> existing.add(entry.getValue()))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.printf("After: %s%n", map);  

for example :

Before: {A=1, B=2, C=2, D=3, E=3} After: {A=1, B=2, D=3}
NizarETH
  • 969
  • 3
  • 15
  • 38
0

I think there are a couple of questions you should think about. Is the query wrong or is the way I save contacts wrong?

In your app should contacts be allowed to be duplicated? If no you could add a unique constraint to your migration. See Sql Lite Unique Constraints

If your DB should be accepting duplicate values, then you should add a column that signifies the unique ones to that user? Ie userId column or a place the contact is associated with and then add that into your query as Selection and SelectionArgs.

Lastly if you are just looking for a quick fix... you should dive deeper into your filtering.

Your code contactsList.contains(contacts) will never be true because you are always creating the contact on the line above. Then you are checking if your list contains that newly created one. Otherwise you can use the above solution https://stackoverflow.com/a/64535787/5398130

0

You can override equals() method in class Contacts. This way your contactList.contains(Contact c) can evaluate to true if two contact objects are logically equals from your override method, and thus it will not add it to the list again.

     @Override
     public boolean equals(Object o){
          if(!o.getClass().equals(Contacts.class)) return false;
          Contact c2 = (Contact)o;
          // if phonenumber is unique to differentiate contact
          return c2.number.equals(number);
      }
0

You can change List with HashSet. HashSet prevents to have duplicate items. Your final code should be like that:

 RecyclerView recyclerView;
 HashSet<Contacts> contactsSet;
 ContactsAdapter adapter;

 public void getContactList() {
    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null,
            "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

        Contacts contacts = new Contacts(name, number);
        contactsSet.add(contacts);
    }
    List<Contacts> contactsList = new ArrayList<>();
    adapter = new ContactsAdapter(contactsList, getApplicationContext());
    recyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}
ycannot
  • 1,807
  • 1
  • 9
  • 20
-1

You can follow these steps on this page where i can provide the full solution here is the link

Syed Rafaqat Hussain
  • 1,009
  • 1
  • 9
  • 33