0

User picks a contact from their contacts and this is the callback function (I'm skipping onActivityResult(...) code, it's working fine):

private User addUserFromContactData(Intent data) {
    Uri contactData = data.getData();

    // Cursor loader to query contact information
    CursorLoader cl = new CursorLoader(this);
    String[] projection = { ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Email.DATA };
    cl.setProjection(projection);
    cl.setUri(ContactsContract.CommonDataKinds.Email.CONTENT_URI);
    cl.setSelection(ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?");
    cl.setSelectionArgs(new String[] { contactData.getLastPathSegment() });

    // Execute query and get results from cursor
    Cursor c = cl.loadInBackground();
    final int nameIndex = c.getColumnIndex(projection[0]);
    final int emailIndex = c.getColumnIndex(projection[1]);

    User user = null;
    if (c.moveToFirst()) {
        user = new User();
        user.setName(c.getString(nameIndex));
        user.setEmail(c.getString(emailIndex));
    }

    c.close();
    return user;
}

This method is working fine with contacts that have an email address. But when I select a contact without it, no results are found. Email is optional for me, so if there is no email, I will only use the contact name. Seems like I'm only selecting contacts with email address.

Can anyone help me? Maybe I need to query twice, first time to get name and second to get optional email?

Thanks guys.

jelies
  • 9,110
  • 5
  • 50
  • 65
  • If you know that you have contacts that don't have an email then you shouldn't use a `where` clause based on that email field. I haven't work that much with the contacts API but couldn't you use the `ContactsContract.Contacts.CONTENT_URI` to query the contacts and retrieve the one where `CONTACT_ID` is the one resulted from the `PICK`? Then you can retrieve all the information from that particular contact, including the email field. – user Sep 28 '12 at 09:11
  • Uhm, I tried changing only `WHERE` clause, but without modifying`Uri`. Makes sense changing accordingly `Uri`. I will try this later. Thanks @Luksprog! :) – jelies Sep 28 '12 at 09:41
  • Try to use my answer here: http://stackoverflow.com/a/18401101/1735499 Hope this will help :) – Frank Nguyen Aug 23 '13 at 11:11

1 Answers1

2

Solved. To accomplish this, two queries are required (correct me if I can do the same with only one):

private User addUserFromContactData(Intent data) {
    Uri contactData = data.getData();

    // Cursor loader to query contact name
    CursorLoader clName = new CursorLoader(this);
    clName.setProjection(new String[] { ContactsContract.Contacts.DISPLAY_NAME });
    clName.setUri(ContactsContract.Contacts.CONTENT_URI);
    clName.setSelection(ContactsContract.Contacts._ID + " = ?");
    clName.setSelectionArgs(new String[] { contactData.getLastPathSegment() });

    // Cursor loader to query optional contact email
    CursorLoader clEmail = new CursorLoader(this);
    clEmail.setProjection(new String[] { ContactsContract.CommonDataKinds.Email.DATA });
    clEmail.setUri(ContactsContract.CommonDataKinds.Email.CONTENT_URI);
    clEmail.setSelection(ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?");
    clEmail.setSelectionArgs(new String[] { contactData.getLastPathSegment() });

    // Execute queries and get results from cursors
    Cursor cName = clName.loadInBackground();
    Cursor cEmail = clEmail.loadInBackground();
    final int nameIndex = cName.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
    final int emailIndex = cEmail.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);

    User user = null;
    if (cName.moveToFirst()) {
        user = new User();
        user.setName(cName.getString(nameIndex));
    }

    // This only could be true if selected contact has at least one email
    if (cEmail.moveToFirst() && user != null) {
        user.setEmail(cEmail.getString(emailIndex));
    }

    cName.close();
    cEmail.close();
    return user;
}

Thanks for the clue @Luksprog! In previous code I was only querying contacts with email, because CursorLoader's Uri was ContactsContract.CommonDataKinds.Email.CONTENT_URI.

Community
  • 1
  • 1
jelies
  • 9,110
  • 5
  • 50
  • 65