Android: Retrieve contact name from phone number

I would like to retrieve the name of a contact associated with an incoming telephone number. As I process the incoming number in the broascastreceiver having a String with the name of the incoming caller would help my project greatly.

I would think this involves a query using the sql WHERE clause as a filter, but do I need to sort the contacts? An example or hint would be of great assistance.


Solution 1:

Although this has already been answered, but here is the complete function to get the contact name from number. Hope it will help others:

public static String getContactName(Context context, String phoneNumber) {
    ContentResolver cr = context.getContentResolver();
    Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
    Cursor cursor = cr.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
    if (cursor == null) {
        return null;
    }
    String contactName = null;
    if(cursor.moveToFirst()) {
        contactName = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
    }

    if(cursor != null && !cursor.isClosed()) {
        cursor.close();
    }

    return contactName;
}

[Updating based on Marcus's comment]

You will have to ask for this permission:

<uses-permission android:name="android.permission.READ_CONTACTS"/>

Solution 2:

For that you need to use the optimized PhoneLookup provider as described.

Add the permission to AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_CONTACTS"/>

Then:

public String getContactName(final String phoneNumber, Context context)
{
    Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,Uri.encode(phoneNumber));

    String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};

    String contactName="";
    Cursor cursor=context.getContentResolver().query(uri,projection,null,null,null);

    if (cursor != null) {
        if(cursor.moveToFirst()) {
            contactName=cursor.getString(0);
        }
        cursor.close();
    }

    return contactName;
}

Solution 3:

This was very helpful, here's my final code for retrieving the caller's Name, id, and Photo:

private void uploadContactPhoto(Context context, String number) {

Log.v("ffnet", "Started uploadcontactphoto...");

String name = null;
String contactId = null;
InputStream input = null;

// define the columns I want the query to return
String[] projection = new String[] {
        ContactsContract.PhoneLookup.DISPLAY_NAME,
        ContactsContract.PhoneLookup._ID};

// encode the phone number and build the filter URI
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));

// query time
Cursor cursor = context.getContentResolver().query(contactUri, projection, null, null, null);

if (cursor.moveToFirst()) {

    // Get values from contacts database:
    contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup._ID));
    name =      cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));

    // Get photo of contactId as input stream:
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId));
    input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri);

    Log.v("ffnet", "Started uploadcontactphoto: Contact Found @ " + number);            
    Log.v("ffnet", "Started uploadcontactphoto: Contact name  = " + name);
    Log.v("ffnet", "Started uploadcontactphoto: Contact id    = " + contactId);

} else {

    Log.v("ffnet", "Started uploadcontactphoto: Contact Not Found @ " + number);
    return; // contact not found

}

// Only continue if we found a valid contact photo:
if (input == null) {
    Log.v("ffnet", "Started uploadcontactphoto: No photo found, id = " + contactId + " name = " + name);
    return; // no photo
} else {
    this.type = contactId;
    Log.v("ffnet", "Started uploadcontactphoto: Photo found, id = " + contactId + " name = " + name);
}

... then just do whatever you want with "input" (their photo as an InputStream), "name", and "contactId".

And here are the docs listing the ~15 or so columns you have access to, just add them to the projection near the start of the code up above: http://developer.android.com/reference/android/provider/ContactsContract.PhoneLookup.html