Search code examples
androidcontactscontactscontract

The best way to get contacts by using ContactsContract


I am trying to get contacts that are visible in my phonebook. Assume there are 5 contacts with number that are saved in my device and 3 contacts with numbers that are saved in my Gmail acount. Also, consider that device contacts span Gmail contacts. The following method outputs all 8 contacts:

public void getContactList() {
    contactList.clear();

    Cursor phones = null;

    try {
        phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
        while (phones.moveToNext())
        {
            String _name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            String _number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

            HashMap<String , String> contactMap= new HashMap<String, String>();

            contactMap.put("NAME", _name);
            contactMap.put("NUMBER", _number);

            contactList.add(contactMap);
            numbers.add("+" + _number);
            Log.v("" + counter++, _number + " " + _name);
        }
        phones.close();

    } catch ( Exception e ) {
        // TODO: handle exception
    }
    finally {
        if(phones != null){
            phones.close();
        }
    }
}

However, in similar questions, people advise to use the following method. This method outputs 64 lines. In other words, it loops 8 times whatever the first method returns:

public void getContactList() {
    contactList.clear();

    String phoneNum[] = null;
    Cursor cur = null;
    Cursor pCur = null;
    try {
        ContentResolver cr = getContentResolver();
        cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
        int i = 0;

        if (cur.getCount() > 0) {

            phoneNum = new String[cur.getCount()];

            while (cur.moveToNext()) {
                String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                    // get the phone number
                    pCur = cr.query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            null,
                            null,
                            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");

                    while (pCur.moveToNext()) {
                        // int _id = i;
                        String _name = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                        String _number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        _number = _number.replaceAll("[\\D]", "");

                        HashMap<String , String> contactMap= new HashMap<String, String>();

                        contactMap.put("NAME", _name);
                        contactMap.put("NUMBER", _number);

                        contactList.add(contactMap);
                        phoneNum[i] = _number;

                        Log.v("" + counter++, _number + " " + _name);
                    }
                    pCur.close();
                }
                i++;
            }
        }
        cur.close();
    } catch ( Exception e ) {
        // TODO: handle exception
    }
    finally {
        if(pCur != null){
            pCur.close();
        }
        if(cur != null){
            cur.close();
        }
    }
}

If people advise the second method, they should consider a point I fail to notice. However, I could not find out that point yet. Of course, I have no intention to loop my contacts seven more times for no reason. Why people say the second method is better? What kind of favor or verification is done by this?


Solution

  • If you just want the DISPLAY_NAME and PHONE_NUMBER of all the visible contacts your method is perfect.

    The second method is useful when you want to group multiple phone numbers of a contact in a single data structure, but what you missed is that the second query should also have the contact id as the filter otherwise you are simply querying all the phone numbers of all the contacts instead of querying for all phone numbers of a single contact.