0

I am using https://trinitytuts.com/get-contact-list-and-show-in-custom-listview-android/# tutorial to get contact list in list view. It is working fine but giving duplicate contacts. Can some one guide over this to resolve and get contact once only in the listview.

Code for Mainactivity is as below:

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity {

    // ArrayList
    ArrayList<SelectUser> selectUsers;
    List<SelectUser> temp;
    // Contact List
    ListView listView;
    // Cursor to load contacts list
    Cursor phones, email;

    // Pop up
    ContentResolver resolver;
    SearchView search;
    SelectUserAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        selectUsers = new ArrayList<SelectUser>();
        resolver = this.getContentResolver();
        listView = (ListView) findViewById(R.id.contacts_list);

        phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        LoadContact loadContact = new LoadContact();
        loadContact.execute();

        search = (SearchView) findViewById(R.id.searchView);

        //*** setOnQueryTextListener ***
        search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                // TODO Auto-generated method stub

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // TODO Auto-generated method stub
                adapter.filter(newText);
                return false;
            }
        });
    }

    // Load data on background
    class LoadContact extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected Void doInBackground(Void... voids) {
            // Get Contact list from Phone

            if (phones != null) {
                Log.e("count", "" + phones.getCount());
                if (phones.getCount() == 0) {
                    Toast.makeText(MainActivity.this, "No contacts in your contact list.", Toast.LENGTH_LONG).show();
                }

                while (phones.moveToNext()) {
                    Bitmap bit_thumb = null;
                    String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
                    String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    String EmailAddr = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA2));
                    String image_thumb = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
                    try {
                        if (image_thumb != null) {
                            bit_thumb = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(image_thumb));
                        } else {
                            Log.e("No Image Thumb", "--------------");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    SelectUser selectUser = new SelectUser();
                    selectUser.setThumb(bit_thumb);
                    selectUser.setName(name);
                    selectUser.setPhone(phoneNumber);
                    selectUser.setEmail(id);
                    selectUser.setCheckedBox(false);
                    selectUsers.add(selectUser);
                }
            } else {
                Log.e("Cursor close 1", "----------------");
            }
            //phones.close();
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            adapter = new SelectUserAdapter(selectUsers, MainActivity.this);
            listView.setAdapter(adapter);

            // Select item on listclick
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                    Log.e("search", "here---------------- listener");

                    SelectUser data = selectUsers.get(i);
                }
            });

            listView.setFastScrollEnabled(true);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        phones.close();
    }
}
Panache
  • 1,701
  • 3
  • 19
  • 33

2 Answers2

2

Why not use a Set?Try storing your contacts in a an Object and that Object in a Set. Remember to override the equals method of that Object based on which you need to eliminate duplicates.

More reading here http://www.java2novice.com/java-collections-and-util/hashset/duplicate/

log N
  • 925
  • 9
  • 33
  • if I just change Arraylist to Hashset keeping everything same, the list size came to 30 from 2973. So skipping most of contact to be added in set. How can this be used. – Panache Jan 28 '17 at 03:54
  • You will have to add your contacts to be displayed in an Object i.e Contacts object(say). Then in the contacts object you need to override the equals methods and based upon any criteria you will need to return true or false. Rest all will be managed internally by HashSet. – log N Jan 28 '17 at 13:07
0

You're seeing duplicate contacts because you're querying over a list of phones, not contacts, if a contact has more then one phone, you'll get the same contact multiple times - one for each phone number.

You need to decide how you want to handle contacts with multiple phones, and also contacts without any phone (currently you're not displaying contacts that don't have any phone).

Assuming you want one line per contact, displaying only contacts that have phones, and displaying all phones for that contact on the same row, you'll need to revise your code a bit:

  1. The SelectUser object should accept a list of phones, not just one.
  2. the selectUsers field should be HashMap<Long, SelectUser> and not ArrayList<SelectUser>
  3. String id = ... should actually be Long id = ...

Then in your cursor iterator do this:

if (selectUsers.containsKey(id)) {
    SelectUser selectUser = selectUsers.get(id);
    selectUser.addPhone(phoneNumber); // new method you need to implement
} else {
    SelectUser selectUser = new SelectUser();
    selectUser.setThumb(bit_thumb);
    selectUser.setName(name);
    selectUser.setPhone(phoneNumber);
    selectUser.setEmail(id); // Email can't be retrieved from the phones table, see below
    selectUser.setCheckedBox(false);
    selectUsers.add(selectUser);
}

P.S. You can't read CommonDataKinds.Email fields when querying the CommonDataKinds.Phone table, if you want to read both phones and emails on the same query, you need to query over the ContactsContract.Data table, and select for Data.MIMETYPE + ' = ' + Phone.CONTENT_TYPE + ' OR ' + Data.MIMETYPE + ' = ' + Email.CONTENT_TYPE. This will give you a cursor over lines that are either phone or email (you can use the Data.MIMETYPE to check which one is it.

See more info here: https://developer.android.com/reference/android/provider/ContactsContract.Data.html https://stackoverflow.com/a/31864811/819355

Community
  • 1
  • 1
marmor
  • 27,641
  • 11
  • 107
  • 150