Android: Retrieve contact name from phone number
AndroidAndroid ContactsPhone NumberContactscontractAndroid Problem Overview
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.
Android Solutions
Solution 1 - Android
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 - Android
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 - Android
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
Solution 4 - Android
This version is the same as Vikram.exe's answer with code to avoid the ANR
interface GetContactNameListener {
void contactName(String name);
}
public void getContactName(final String phoneNumber,final GetContactNameListener listener) {
new Thread(new Runnable() {
@Override
public void run() {
ContentResolver cr = getContentResolver();
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
if (cursor == null) {
return;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
listener.contactName(contactName);
}
}).start();
}
Solution 5 - Android
Pass the contact number from which you are getting the call in the following method. This Method will check whether the contact is saved in your mobile or not. If the contact is saved then it will return the contact name otherwise it return a string unknown number
Add this code in your Broadcast receiver class
public String getContactDisplayNameByNumber(String number,Context context) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
name = "Incoming call from";
ContentResolver contentResolver = context.getContentResolver();
Cursor contactLookup = contentResolver.query(uri, null, null, null, null);
try {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToNext();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
// this.id =
// contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.CONTACT_ID));
// String contactId =
// contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
}else{
name = "Unknown number";
}
} finally {
if (contactLookup != null) {
contactLookup.close();
}
}
return name;
}
to get Source code visit this link
Solution 6 - Android
For that, we can use the PhoneLookup
provider to get the names or contact details using the mobile number.
Add the permission to AndroidManifest.xml
:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
Add the following custom kotlin method in your activity and call the same with the required mobile number.
fun getContactNameByPhoneNumber(context: Context, phoneNumber: String): String? {
var phone = phoneNumber
if(phoneNumber != null && phoneNumber.length > 0 && phoneNumber[0].equals('+'))
phone = phoneNumber.substring(3)
val projection = arrayOf(
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
)
val cursor = context.contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection,
ContactsContract.CommonDataKinds.Phone.NUMBER, null, null
) ?: return ""
for (i in 0 until cursor.count) {
cursor.moveToPosition(i)
val nameFieldColumnIndex = cursor
.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)
val phoneFieldColumnIndex = cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
if(phone.equals(cursor.getString(phoneFieldColumnIndex)))
return cursor.getString(nameFieldColumnIndex)
}
return "Unknown"
}
For more: https://developer.android.com/training/contacts-provider/retrieve-names