Search code examples
cursorandroid-contactscontactscontract

ContactsContract.Contacts issue, duplicates


I've been doing research on this but I can't figure it out. My contacts in my phone in a sample app I downloaded are often duplicated, like so:

enter image description here

I'm quite sure it has something to do with ContactsContract.Contacts. I've read up on it but don't know how to implement it in my code. Could someone help (or indeed if there's another way of doing it). I just want each contact be listed once, not multiple time.

According to http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html :

ContactsContract.Contacts
Constants for the contacts table, which contains a record per aggregate of raw contacts representing the same person.

I have 3 java files in my project, MainActivity, SelectUser and SelectUserAdapter, but I believe MainActivity is the one pertaining to this problem. Probably specifically this line :

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

If you need more code just let me know.

Here's my MainActivity.java :

package com.example.chris.contactlistcustomlistview;

        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");
//        retrieves contact information
        LoadContact loadContact = new LoadContact();
        loadContact.execute();

//        let's set up our search box,
        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) {
                // when the text in searchView changes, call the filter function
                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();
                    }
//what's happening here? For every user in the phonebook, show an image, the name, number, an id and maybe a checkbox?
                    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
//        when DoInBackground is finished, when we have our phone number, name etc... display the results in our listview.
        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();
    }
}

Solution

  • public class MainActivity extends Activity {
    
    
        Cursor cursor;
        ListView mainListView;
        ArrayList hashMapsArrayList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (cursor != null) {
                cursor.moveToFirst();}
            try {
    
                cursor = getApplicationContext().getContentResolver()
                        .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
                int Idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
                int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    
                int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                int photoIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI);
                cursor.moveToFirst();
    
    
                Set<String> ids = new HashSet<>();
                do {
                    System.out.println("=====>in while");
                    String contactid=cursor.getString(Idx);
                    if (!ids.contains(contactid)) {
                        ids.add(contactid);
                        HashMap<String, String> hashMap = new HashMap<String, String>();
                       String  name = cursor.getString(nameIdx);
                        String phoneNumber = cursor.getString(phoneNumberIdx);
                        String image = cursor.getString(photoIdIdx);
                        System.out.println("Id--->"+contactid+"Name--->"+name);
                        System.out.println("Id--->"+contactid+"Name--->"+name);
                        System.out.println("Id--->"+contactid+"Number--->"+phoneNumber);
    
                        if (!phoneNumber.contains("*")) {
                            hashMap.put("contactid", "" + contactid);
                            hashMap.put("name", "" + name);
                            hashMap.put("phoneNumber", "" + phoneNumber);
                            hashMap.put("image", "" + image);
                            // hashMap.put("email", ""+email);
                            if (hashMapsArrayList != null) {
                                hashMapsArrayList.add(hashMap);}
    //                    hashMapsArrayList.add(hashMap);
                        }
                    }
    
                } while (cursor.moveToNext());
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
    }
    }