I am trying to get first name and last name in contact book by phone number.
Here is my code:
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cResolver.query(uri, null, null, null, null);
if(cursor != null && cursor.moveToFirst()) {
int idColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
int firstNameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
int lastNameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
while (!cursor.isAfterLast()) {
long id = cursor.getLong(idColumnIndex);
contact = new MyContact();
contact.setId(id);
contact.setFirstName(cursor.getString(firstNameIndex));
contact.setLastName(cursor.getString(lastNameIndex));
}
cursor.close();
}
But firstNameIndex and lastNameIndex is always -1. What I am doing wrong ? Please help me.
PhoneLookup is a nice and quick way to get contact data by a phone number, but it returns a cursor limited to the columns mentioned in the docs.
You can see there's DISPLAY_NAME you can access, but not GIVEN_NAME, FAMILY_NAME.
GIVEN_NAME & FAMILY_NAME are fields stored in the Data table, which means you need to query that table separately to get to those fields.
So, you can just add another query using the contact ID you got from PhoneLookup (note that for each looked up phone there might be multiple contacts returned).
Here's a sample method to get first/last names from contact ID:
private void addNames(MyContact contact, long contactId) {
String[] projection = new String[] {StructuredName.GIVEN_NAME, StructuredName.FAMILY_NAME};
// filter to just StructuredName rows from the data table for the given contact
String selection = Data.CONTACT_ID + "=" + contactID + " AND " + Data.MIMETYPE + "=" + StructuredName.CONTENT_ITEM_TYPE;
Cursor cursor = getContentResolver().query(Data.CONTENT_URI, projection, selection, null, null);
if (cursor.next()) {
contact.setFirstName(cursor.getString(0));
contact.setLastName(cursor.getString(1));
}
cursor.close();
}
I am trying to find the contact details corresponding to an sms from the phone's sms inbox. From my understanding the person column is a foreign key to the _id column of ContactsContract.Contacts.
My problem is that I am getting wrong values for the person value from the sms query. Some person ids don't exist in the contact table and some are pointing to totally different contact.
Below is the code that I use for fetching the list of person values, Can anyone tell me if I missed something or faced a similar problem.
Tested with Nexus S running Android 4.1.2
Uri parsedUri = Uri.parse("content://sms/inbox");
String[] projection = new String[] { "_id", "address", "person" };
Cursor cursor = contentResolver.query(parsedUri, projection, null, null, null);
Log.d(TAG, "Total Count " + cursor.getCount());
if (cursor.getCount() > 0) {
// String address;
int person;
int personIndex = cursor.getColumnIndex("person");
if (cursor.moveToFirst())
do {
person = cursor.getInt(personIndex);
if (person > 0) {
// Add this id to a list
}
} while (cursor.moveToNext());
}
cursor.close();
Update: I was looking at some documentation from the Android Developer Portal (http://developer.android.com/guide/topics/providers/contacts-provider.html), Is it possible that the person id that is retrieved from the sms inbox is referring to the ContactsContract.RawContacts instead of ContactsContract.Contacts as I have done.
Indeed the person column in the sms inbox refers to a RawContacts entry's id. By querying the RawContacts table you can find the contact_id for the Contacts table for the specific user.
You can try this code to get the contact id from the RawContacts table..
long contactId = 0;
Uri uri = ContactsContract.RawContacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID };
Cursor cursor = contentResolver.query(uri, projection,
ContactsContract.RawContacts._ID + " = ?",
new String[] { rawContactId }, null);
if (cursor.moveToFirst()) {
int contactIdIndex = cursor.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID);
contactId = cursor.getLong(contactIdIndex);
}
cursor.close();
This should solve your problem for fetching the correct contact details by reading an sms row in Android. However as the sms data provider is not documented and phone manufacturers may use them differently, there is chance that this approach may not work on phones other than pure android.
You first check that person number is exits in contact list or not.if yes then match both id.
Cursor cursor=managedQuery(uri, null, null, null, null);
while (cursor.moveToNext()) {
String contactId = cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Boolean.parseBoolean(hasPhone)) {
// You know have the number so now query it like this
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(
phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}
}
I'm trying to find a contact by display name. The goal is to open this contact and add more data to it (specifically more phone numbers), but I'm struggling to even find the contact I want to update.
This is the code I'm using:
public static String findContact(Context context) {
ContentResolver contentResolver = context.getContentResolver();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI;
String[] projection = new String[] { PhoneLookup._ID };
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " = ?";
String[] selectionArguments = { "John Johnson" };
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);
if (cursor != null) {
while (cursor.moveToNext()) {
return cursor.getString(0);
}
}
return "John Johnson not found";
}
I do have a contact called "John Johnson", but the method always returns "not found". I also tried searching for a contact with just one name, so that makes no difference.
I suspect that it's something wrong with the uri, selection or selection arguments, because I couldn't find any example online of searching for contacts with a given display name, and it seems display name is a special kind of information, different from for example a phone number.
Any ideas how I can achieve to find John Johnson?
UPDATE: I found out how to find a contact by display name:
ContentResolver contentResolver = context.getContentResolver();
Uri uri = Data.CONTENT_URI;
String[] projection = new String[] { PhoneLookup._ID };
String selection = StructuredName.DISPLAY_NAME + " = ?";
String[] selectionArguments = { "John Johnson" };
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);
if (cursor != null) {
while (cursor.moveToNext()) {
return cursor.getString(0);
}
}
return "John Johnson not found";
This code returns the contact id of the first contact with display name "John Johnson". In my original code I had the wrong uri and the wrong selection in my query.
I thinks the issue may caused by the projection you set. Projection is used to tell android which column of data you want to query then you only give the id column so the display name won't return. Try to remove the projection to see whether it works.
-- Cursor cursor = contentResolver.query(uri, projection, selection, selectionArguments, null);
++ Cursor cursor = contentResolver.query(uri, null, selection, selectionArguments, null);
Change Your Query URI.
You are using a URI that is meant to filter only phones numbers:
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI;
You need to use a URI that has access to the display_name column, like this:
Uri uri = ContactsContract.Data.CONTENT_URI;
There's a decent breakdown of what URIs to use and when to use them on the Android SDK Documentation:
If you need to read an individual contact, consider using CONTENT_LOOKUP_URI instead of CONTENT_URI.
If you need to look up a contact by the phone number, use PhoneLookup.CONTENT_FILTER_URI, which is optimized for this purpose.
If you need to look up a contact by partial name, e.g. to produce filter-as-you-type suggestions, use the CONTENT_FILTER_URI URI.
If you need to look up a contact by some data element like email address, nickname, etc, use a query against the ContactsContract.Data table. The result will contain contact ID, name etc.
//method for gaining id
//this method get a name and make fetch it's id and then send the id to other method //named "showinformation" and that method print information of that contact
public void id_return(String name) {
String id_name=null;
Uri resultUri = ContactsContract.Contacts.CONTENT_URI;
Cursor cont = getContentResolver().query(resultUri, null, null, null, null);
String whereName = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME + " = ?" ;
String[] whereNameParams = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,name};
Cursor nameCur = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur.moveToNext()) {
id_name = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID));}
nameCur.close();
cont.close();
nameCur.close();
//for calling of following method
showinformation(id_name);
}
//method for showing information like name ,phone, email and other thing you want
public void showinformation(String id) {
String name=null;
String phone=null;
String email=null;
Uri resultUri = ContactsContract.Contacts.CONTENT_URI;
Cursor cont = getContentResolver().query(resultUri, null, null, null, null);
String whereName = ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID+ " = ?" ;
String[] whereNameParams1 = new String[] { ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,id};
Cursor nameCur1 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams1, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur1.moveToNext()) {
name = nameCur1.getString(nameCur1.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));}
nameCur1.close();
cont.close();
nameCur1.close();
String[] whereNameParams2 = new String[] { ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,id};
Cursor nameCur2 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams2, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur2.moveToNext()) {
phone = nameCur2.getString(nameCur2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));}
nameCur2.close();
cont.close();
nameCur2.close();
String[] whereNameParams3 = new String[] { ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,id};
Cursor nameCur3 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams3, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
while (nameCur3.moveToNext()) {
email = nameCur3.getString(nameCur3.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));}
nameCur3.close();
cont.close();
nameCur3.close();
String[] whereNameParams4 = new String[] { ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE,id};
Cursor nameCur4 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, whereName, whereNameParams4, ContactsContract.CommonDataKinds.StructuredPostal.DATA);
while (nameCur4.moveToNext()) {
phone = nameCur4.getString(nameCur4.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.DATA));}
nameCur4.close();
cont.close();
nameCur4.close();
//showing result
txadd.setText("Name= "+ name+"\nPhone= "+phone+"\nEmail= "+email);
}
//thank all persons in this site because of many help of me to learn and correction my warn and errors this is only a gift for all of you and ...
The below code should do the trick
if (displayName != null) {
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI, Uri.encode(displayName));
String[] displayNameProjection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME };
Cursor cur = context.getContentResolver().query(lookupUri, displayNameProjection, null, null, null);
try {
if (cur.moveToFirst()) {
return true;
}
} finally {
if (cur != null)
cur.close();
}
return false;
} else {
return false;
}
Reference: Retrieving a List of Contacts Article
Hi I am trying to get a contacts first name. I know how to get a contacts full name, but I cannot figure out how obtain just the name. any ideas?
Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] mPhoneNumberProjection = { PhoneLookup._ID, PhoneLookup.NUMBER, PhoneLookup.DISPLAY_NAME };
Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null);
try {
if (cur.moveToFirst()) {
String name = cur.getString(2);
// do something with the name
}
} finally {
cur.close();
}
I haven't personally tried this, but you may have to do a further RawContacts.CONTENT_URI query against the PersonLookup.LOOKUP_KEY from the first query, allowing you to retrieve the StructuredName.GIVEN_NAME field.
I have a Cursor points to a Contact. How can I get an url built from that Cursor?
I need to know that because from here
http://developer.android.com/guide/topics/providers/content-providers.html
I need to have an url so that I can build a phone uri, like this:
phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
and I can query all the phone numbers for that contact.
You can use the following query to retrieve all numbers for a certain contact:
/* the following line assumes that the contactCursor you described
* has the People._ID column at index 0 in its projection. */
int contactId = contactCursor.getInt(0);
Cursor numberCursor = getContentResolver().query(Phones.CONTENT_URI,
new String[] {Phones.NUMBER}, Phones.PERSON_ID + "=" + contactId, null, null);
while(cursor.moveToNext()) {
String number = cursor.getString(0);
}
cursor.close();