Skip to content Skip to sidebar Skip to footer

How To Avoid Duplicate Contact Name (data ) While Loading Contact Info To Listview?

I am populating contact list details to list view successfully. My code: String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ' ASC'; Cursor curLog = getC

Solution 1:

I have used a rough way to avoid this problem which helped me so much and working nicely.

i.e

Use local database (SQLite) to avoid duplicate data by make phone number to unique.

I have made one SQLite DB to handle this problem:

ContactMerger.java:

publicclassContactMerger {

privatestaticfinalStringCONTACT_TABLE="_contact_table";
privatestaticfinalStringCONTACT_ID="_contactId";
privatestaticfinalStringCONTACT_NAME="_contactName";
privatestaticfinalStringCONTACT_MOBILE_NUMBER="_contactNumber";
privatestaticfinalStringCONTACT_DATE="_contactDate";


privatestaticfinalintDATABASE_VERSION=1;
privatestaticfinalStringDATABASE_NAME="DB_Contact";

privatefinal Context context;
private SQLiteDatabase ourDatabase;
private DbHelper ourHelper;

privateclassDbHelperextendsSQLiteOpenHelper {

    publicDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @OverridepublicvoidonCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stubStringcontactQuery="CREATE TABLE " + CONTACT_TABLE + " ("
                + CONTACT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + CONTACT_NAME + " TEXT NOT NULL, " + CONTACT_DATE
                + " TEXT NOT NULL, " + CONTACT_MOBILE_NUMBER
                + " TEXT NOT NULL UNIQUE);";

        db.execSQL(contactQuery);
    }

    @OverridepublicvoidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS " + CONTACT_TABLE);
        onCreate(db);
    }

}

publicContactMerger(Context context) {
    this.context = context;
}

public ContactMerger open()throws SQLException {
    ourHelper = newDbHelper(context);
    ourDatabase = ourHelper.getWritableDatabase();
    returnthis;
}

publicvoidclose() {
    ourHelper.close();
}

// Insert Data to Contact TablepubliclonginsertContacts(String name, String number, String date)throws SQLException {
    ContentValuescv=newContentValues();
    cv.put(CONTACT_NAME, name);
    cv.put(CONTACT_DATE, date);
    cv.put(CONTACT_MOBILE_NUMBER, number);
    Log.d("Insert Data", cv.toString());
    return ourDatabase.insert(CONTACT_TABLE, null, cv);
}

//Get Contact details from Contact Tablepublic ArrayList<ContactHolder> getContactDetails()throws Exception{
    ArrayList<ContactHolder> contactDetails = newArrayList<ContactHolder>();
    String[] columns = newString[] { CONTACT_ID, CONTACT_NAME, CONTACT_DATE, CONTACT_MOBILE_NUMBER };
    Cursorc= ourDatabase.query(CONTACT_TABLE, columns, null, null, null,null, null);

    intiContactName= c.getColumnIndex(CONTACT_NAME);  
    intiContactDate= c.getColumnIndex(CONTACT_DATE);  
    intiContactMobileNumber= c.getColumnIndex(CONTACT_MOBILE_NUMBER);

    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {

        ContactHolderdata=newContactHolder();
        data.setName(c.getString(iContactName));
        data.setDate(c.getString(iContactDate));
        data.setNumber(c.getString(iContactMobileNumber));

        contactDetails.add(data);
    }

    return contactDetails;
 }
}

Here ContactHolder is just a getter/setter class to handle contact entities.

First I inserted all Contact information once in my MainActivity by the help of a background thread. It prevents to insert the contact info multiple times.

Something like:

private ArrayList<ContactHolder> contactHolder;
privatevoidsetCallLogs(Cursor managedCursor) {
    contactHolder = new ArrayList<ContactHolder>();

    int _number = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    int _name = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int _id = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);


    while (managedCursor.moveToNext()) {

        ContactHolder holder = new ContactHolder();
        holder.setNumber(managedCursor.getString(_number));
        holder.setName(managedCursor.getString(_name));
        holder.setDate(managedCursor.getString(_id));
        contactHolder.add(holder);
    }
    Thread t = new Thread(new Runnable() {

        @Override
        publicvoidrun() {
            for(int i=0; i<contactHolder.size(); i++){
                try{
                    ContactMerger merger = new ContactMerger(HomeActivity.this);
                    merger.open();
                    merger.insertContacts(contactHolder.get(i).getName(),
                            contactHolder.get(i).getNumber(),
                            contactHolder.get(i).getdate());
                    merger.close();

                } catch(Exception e){
                     e.printStackTrace();
                }
            }

        }
    });

    t.start();  

}

At last I gtt all contact information inside an Asynctask(doInbackground()) and put in adapter/listview in its onPostExecute() method in the class I want to show.

Here:

@Overrideprotected ArrayList<ContactHolder> doInBackground(String... parameters) {
        ArrayList<ContactHolder> filterContacts = newArrayList<ContactHolder>();
        ContactMergermerger=newContactMerger(Aaja_Contact.this);
        merger.open();
        try {
            filterContacts = merger.getContactDetails();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        merger.close();

        return filterContacts;
    }

Solution 2:

I believe this may happen if the contact number is stored in two different ways/formats: for example in your case the number for Akshay may be saved as 982-0123456 and 9820123456

Did you try displaying the number along with the Name by including the Number as well in the list view?

Solution 3:

You need to retrieve the data from the Cursor to HashSet (which don't allows duplicate itmes) and then pass the HashSet object to your ListView's Adapter

This is a dump solution but it will help you:

ListView listView;
Set<String> listItems;

@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    listView = (ListView) findViewById(R.id.listView);
    listItems = newHashSet<String>();

    String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
    Cursor curLog =  getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order); 

    if(curLog != null) {
        while(curLog.moveToNext()) {
            String str = curLog.getString(curLog.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY));
            listItems.add(str);
        }
    }

    String listString = listItems.toString();
    listString = listString.substring(1,listString.length()-1);
    String[] newList = listString.split(", ");

    ArrayAdapter<String> adapter = newArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, newList);
    listView.setAdapter(adapter);        
}

Good luck..

Solution 4:

Since you're querying Phone.CONTENT_URI, I'm assuming you're looking for contacts with phone number.. then you can use ContactsContract.Contacts.CONTENT_URI

Stringorder= ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
CursorcurLog= getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
                ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?", newString[] { "1" }, order);

Solution 5:

Its because the listview is showing both normal contacts as well as whatsapp( or like this) linked contacts. Best is to store all the contacts in a Database and then retrieve the contacts using "select distinct..." command of SQL.

Post a Comment for "How To Avoid Duplicate Contact Name (data ) While Loading Contact Info To Listview?"