9

Currently I am displaying all the contacts of my phone in my app as a custom recyclerview. Till now I am showing name, mobile number and profile image of the contact on the list item view but I need to get all the information for that contact and display it when the list item of my app is clicked in a custom detail page.

For each contact there is a different set of information available, like in few contacts I have email but for few contacts its not present.

My questions are

  1. How can I get all the information of a given contact without missing a single bit.Is there a structure that I can traverse and check value for each key?

  2. Also when I am populating the system contacts in my apps list, I find same contact multiple times in the list. I think this is due to the fact that in my device's account manager the same number is registered for many accounts like whatsapp, gmail. If so how to display that number only once in my list.

Manish Patiyal
  • 4,427
  • 5
  • 21
  • 35

3 Answers3

1

Here is what you can do: you will have your contact id so base on that you can save details like phone numbers ,emails in your custom object and use that object to display details

Custom class like this:

class Contact
{
    int contactId;
    String Name;
    ArrayList<Phone> phone;
    ArrayList<Email> emails;
}

class Phone
{
    String PhoneType;
    String number;
}

class Email 
{
    String type;
    String EmailId;
}

Retrieve detail and add it to your custom class:

ContentResolver cr = getContentResolver();
    Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
        "DISPLAY_NAME = '" + NAME + "'", null, null);
    if (cursor.moveToFirst()) {
        String contactId =
            cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
        //
        //  Get all phone numbers.
        //
        Cursor phones = cr.query(Phone.CONTENT_URI, null,
            Phone.CONTACT_ID + " = " + contactId, null, null);
        while (phones.moveToNext()) {
            String number = phones.getString(phones.getColumnIndex(Phone.NUMBER));
            int type = phones.getInt(phones.getColumnIndex(Phone.TYPE));
            switch (type) {
                case Phone.TYPE_HOME:
                    // do something with the Home number here...
                    break;
                case Phone.TYPE_MOBILE:
                    // do something with the Mobile number here...
                    break;
                case Phone.TYPE_WORK:
                    // do something with the Work number here...
                    break;
                }
        }
        phones.close();
        //
        //  Get all email addresses.
        //
        Cursor emails = cr.query(Email.CONTENT_URI, null,
            Email.CONTACT_ID + " = " + contactId, null, null);
        while (emails.moveToNext()) {
            String email = emails.getString(emails.getColumnIndex(Email.DATA));
            int type = emails.getInt(emails.getColumnIndex(Phone.TYPE));
            switch (type) {
                case Email.TYPE_HOME:
                    // do something with the Home email here...
                    break;
                case Email.TYPE_WORK:
                    // do something with the Work email here...
                    break;
            }
        }
        emails.close();
    }
    cursor.close();

Hope this will help

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
KDeogharkar
  • 10,939
  • 7
  • 51
  • 95
  • you have nicely covered the name, phone number and email but there are other fields as well in a contact as I was asking for a way to parse all the data that belongs to a given contact. For example, Address part in android devices includes Street, City, State Postcode and country. There may be other fields like Web address, Organisation, Notes, NickName, Relationship. also events like birthdays. Now if a contact carries all this information how can I retrieve it. That was my first question. – Manish Patiyal Mar 31 '16 at 05:54
  • this snippet is just example how you can cover detail in your custom class . so that way only you will have to put all the details in your custom class and create separate custom class as per details like nickname,relationship etc; you will get all KEY_CONSTANTS for all detail you need from contact only . you only have to add it in your custom class thats it. hope this idea will help you. happy coding. – KDeogharkar Mar 31 '16 at 05:57
0

maybe this method help you:

  public void getAllContacts() {


    //region searchlist
    ArrayList<SearchResult> results = new ArrayList<>();

    ContentResolver cr = SearchFragment.this.getActivity().getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    if (cur == null)
        return;
    if (cur.getCount() < 1)
        return;

    while (cur.moveToNext()) {
        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
        String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
        SearchResult temp = new SearchResult();
        temp.name = name;
        if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
            if (pCur == null)
                continue;
            // i need last phone number but you can add all numbers tu list in while loop
            while (pCur.moveToNext()) {
                temp.phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            pCur.close();
        } else {
            continue;
        }
        String strUri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
        Uri tempUri = null;
        if (strUri != null)
            tempUri = Uri.parse(strUri);
        if (tempUri != null)
            temp.imageUri = tempUri;
        else
            //temp.profilePicture = getActivity().getResources().getDrawable(R.drawable.profile);
            results.add(temp);
            }
//all you want is here in results
    allContacts = results;

    //searchListAdapter.addAll(allContacts);
    //listSearch.setAdapter(searchListAdapter);
    //listSearch.setOnItemClickListener(onItemClickListener);
    //searchListAdapter.notifyDataSetChanged();

    //endregion


}
0

Answer to Q1 :

Refer to the open source "packages/apps/ContactsCommon" package in AOSP. This has the code to read complete data of a contact and load it into data structure. This is the used by the default android screens to render the information. You can reuse the same library without reinventing the wheel.

Answer to Q2 : Ideally such contacts should get joined by default android logic and your list should render aggregate contacts and not raw contacts.

There are multiple answers available for this if you want to remove duplicates from the aggregate list which android failed to aggregate : example : how to remove duplicate contact from contact list in android

Community
  • 1
  • 1
RocketRandom
  • 1,102
  • 7
  • 20