I'm using the contact picker like below to get the id of a contact.
public void pickContact() {
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
intent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
Then I retrieve the contact id from the uri returned by the above using this. And store that as a reference.
public static long getContactIdByUri(Context context, Uri uri)
{
Log.d(TAG, uri.toString());
String[] projection = { Contacts._ID };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
try
{
cursor.moveToFirst();
int idx = cursor.getColumnIndex(Contacts._ID);
long id = -1;
if(idx != -1)
{
id = cursor.getLong(idx);
}
return id;
}
finally
{
cursor.close();
}
}
Later on when a text message arrives I fetch the phone number and based on that I try to look up the contact id using the following.
public static long getContactIdByPhoneNumber(Context context, String phoneNumber) {
ContentResolver contentResolver = context.getContentResolver();
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[] { PhoneLookup._ID };
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor == null) {
return -1;
}
int idx = cursor.getColumnIndex(PhoneLookup._ID);
long id = -1;
if(cursor.moveToFirst()) {
id = cursor.getLong(idx);
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
return id;
}
The problem is that those two id's doesn't match!
So basically the question goes how can I get an id from the contact picker which I can match when looking up a phone number with PhoneLookup.CONTENT_FILTER_URI. Which I can also use to get additional information about the contact?
The url returned from the contact picker refers to the ContactsContract.Data provider which is joined with ContactsContract.RawContacts which again contains CONTACT_ID.
So extracting the actual contact id is trivial using the method below.
public static long getContactIdByDataUri(Context context, Uri uri)
{
String[] projection = new String[] { Data.CONTACT_ID };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
long id = -1;
if(cursor.moveToFirst()) {
id = cursor.getLong(0);
}
return id;
}
Related
I add a custom contact raw to my contacts from my app (like in whatsapp). When I click the custom raw, it open my app. In my viewing activity I check the action and get the content URI from getIntent().getDataString(). It gives me this - content://com.android.contacts/data/10399.
Now I want to get the contact details from this URI. But when I check my contact list using the following code.
void checkContacts(Context context) {
Cursor cursor = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
null, null, null);
if (cursor != null) {
Log.e(TAG, String.valueOf(cursor.getCount()));
try {
while (cursor.moveToNext()) {
Log.e(TAG, cursor.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID)));
Log.e(TAG, "** " + cursor.getString(cursor
.getColumnIndexOrThrow(ContactsContract.Data.RAW_CONTACT_ID)));
}
} finally {
cursor.close();
}
}
}
But i couldn't find any CONTACT_ID or RAW_CONTACT_ID related to 10399.
So how do I get the contact detail from this URI?
I don't want to get all the contacts. I want to get the specific contact related to the URI.
try something like this
Uri uri = data.getData();
String[] projection = {
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
};
Cursor cursor = getApplicationContext().getContentResolver().query(uri, projection,
null, null, null);
cursor.moveToFirst();
int numberColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
String number = cursor.getString(numberColumnIndex);
int nameColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
String name = cursor.getString(nameColumnIndex);
cursor.close();
In my application I try to search a contact using the phonenumber. The phonenumber I am searching with is always in the same format ('123456789' for example).
But the following code retrieves not all contacts I expected.
The main issue might be the different format of phonenumbers in my phone: some contacts are saved with '+12 345 6789', the other with '0123 456789'.
Although I tried ContactsContract.PhoneLookup.NORMALIZED_NUMBER my code retrieves only the contacts saved with phonenumbers in the '123456789'-format.
private String getContactDetails(Context context, String number) {
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.LOOKUP_KEY};
int len = number.length();
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number.substring(len-7)));
String selection = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
selection = ContactsContract.PhoneLookup.NORMALIZED_NUMBER + " LIKE %" + number.substring(len-7) + "%";
}
Cursor cursor = context.getContentResolver().query(contactUri, projection, selection, null, null);
String name = null;
if(cursor != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
cursor.close();
}
return name;
}
Don't use both PhoneLookup.CONTENT_FILTER_URI with selection, CONTENT_FILTER_URIs are used to search for data using the URI itself, and should not get any selection.
The PhoneLookup.NORMALIZED_NUMBER column is for getting the result back in an e164 format, not for querying.
Try this:
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("123456789"));
String[] projection = new String[] { PhoneLookup.NUMBER, PhoneLookup.NORMALIZED_NUMBER };
Cursor c = getContentResolver().query(uri, projection, null, null, null);
if (c != null) {
if (c.moveToFirst()) {
String number = c.getString(0);
String e164_number = c.getString(1);
Log.d(TAG, "number=" + number + ", e164=" + e164_number);
} else {
Log.d(TAG, "couldn't find number");
}
}
c.close();
I know to retrieve the names of contacts that's code below. But what should I change in this code to also have the numbers of phone associated with the contact list?
var uri = ContactsContract.Contacts.ContentUri;
string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName };
var cursor = ManagedQuery(uri, projection, null, null, null);
var contactList = new List<string>();
if (cursor.MoveToFirst())
{
do
{
String phoneNumber = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number));
contactList.Add(cursor.GetString(
cursor.GetColumnIndex(projection[1])));
} while (cursor.MoveToNext());
}
I came across your question while I recently wrote a similar code. The only thing you need in order to retrieve phone numbers, is to:
Make another query to Uri
ContactsContract.CommonDataKinds.Phone.ContentUri;
Set projection to include ContactsContract.CommonDataKinds.Phone.Number; and
Select based on id, i.e. selection parameter should include "_id = " +
contactId
Your query should look like this:
string[] projection = { ontactsContract.CommonDataKinds.Phone.Number };
string selection = "_id = " + contactId;
var cursor = ContentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, projection, selection, null, null);
This query will bring you phone numbers for a contact id but in code below, due to performance issues, I just made one call for all phone numbers and then assign each contract their numbers. Hope it helps.
private List<Contact> GetContactList()
{
List<Contact> contacts = new List<Contact>();
string[] projection = {
ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName,
ContactsContract.Contacts.InterfaceConsts.PhotoUri
};
var uri = ContactsContract.Contacts.ContentUri;
ICursor cursor = ContentResolver.Query(uri, projection, null, null, null);
if (cursor.MoveToFirst())
{
do
{
string id = cursor.GetString(cursor.GetColumnIndex(projection[0]));
string name = cursor.GetString(cursor.GetColumnIndex(projection[1]));
string photoUri = cursor.GetString(cursor.GetColumnIndex(projection[2]));
contacts.Add(new Contact() { Id = long.Parse(id), DisplayName = name, PhotoUri = photoUri });
} while (cursor.MoveToNext());
GetContactPhoneNumber(contacts);
}
return contacts;
}
private async void GetContactPhoneNumber(List<Contact> list)
{
string[] projection =
{
ContactsContract.CommonDataKinds.Phone.Number,
ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId
};
var cursor = ContentResolver.Query(ContactsContract.CommonDataKinds.Phone.ContentUri, projection, null, null, null);
if (cursor.Count > 0)
{
await Task.Factory.StartNew(() =>
{
do
{
try
{
string id = cursor.GetString(cursor.GetColumnIndex(projection[1]));
string phoneNumber = cursor.GetString(cursor.GetColumnIndex(projection[0]));
Contact contact = list.Where(c => c.Id == long.Parse(id)).FirstOrDefault();
contact.PhoneNumber = phoneNumber;
}
catch
{
}
} while (cursor.MoveToNext());
cursor.Close();
});
}
}
I am trying to get details about contact using phone number everything works perfect, but when the contact number is saved with some special characters then i unable to get the contact details below is my code:
//function called
getContactName("+11234567890");
and the same number saved in contact as (+1(123)456-789)
//function
public String getContactName(String number) {
String name;
if(number != null && !number.equals("")){
// 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 != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
cursor.close();
}
}
return name;
}
Use the bellow function to get the name from phone number. I have tested it recently. It works fine. because phone lookup will replace all special character from phone number.
ex- I saved new number 0+0141(12-23) with name Gaurav. And I call the function getContactName(01411223) then it will returns the name Gauav.
Please use following function and let me know if it does not work.
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;
}
You can delete all non digit chars from the string with replaceAll("\\D+","");, have a look and let me know if it works!
public String getContactName(String number) {
number = number.replaceAll("\\D+","");
String name;
if(number != null && !number.equals("")){
// 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 != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
}
cursor.close();
}
}
return name;
}
may be this code will helps
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
I want to get several contact details from a contact list view. I have this code:
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
//HERE I WANT TO GET CONTACT DETAILS FROM THE ID PARAMETER
Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, Uri.encode(id));
Cursor c = getContentResolver().query(lookupUri, new String[]{Contacts.DISPLAY_NAME}, null,null,null);
try {
c.moveToFirst();
String displayName = c.getString(0);
} finally {
c.close();
}
}
But I get this exception: IllegalArgumentException, Invalid lookup id (when I call query method from cursor).
So I dont know how to get a valid lookup id from the item list.
Any idea? thanks!
Here id means, A contact id for which you want to fetch the contact details,
The simply code for getting phone number for a particular contact id is like,
// Build the Uri to query to table
Uri myPhoneUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, id);
// Query the table
Cursor phoneCursor = managedQuery(
myPhoneUri, null, null, null, null);
// Get the phone numbers from the contact
for (phoneCursor.moveToFirst(); !phoneCursor.isAfterLast(); phoneCursor.moveToNext()) {
// Get a phone number
String phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
sb.append("Phone: " + phoneNumber + "\n");
}
}
So, from your question I have to doubt for id parameter which are you sing in your uri just clear that, Also in my example the id is string type...
Hope you will understand it.
Update: Uri.encode(id) instead of just pass id in string format.
Thanks..
Because managedQuery is deprecated you can also use
Cursor phoneCursor = getContentResolver().query(myPhoneUri, null, null, null, null);
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
int columnIndex = arg2.getColumnIndex(ContactsContract.Contacts._ID);
private void retriveContactImage(ImageView imageView, int columnIndex) {
Bitmap photo = null;
try {
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(columnIndex)));
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
imageView.setImageBitmap(photo);
}
private ArrayList<String> retrieveContactNumbers(TextView textView, long contactId) {
ArrayList<String> phoneNum = new ArrayList<String>();
Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { contactId + "" }, null);
if (cursor.getCount() >= 1) {
while (cursor.moveToNext()) {
// store the numbers in an array
String str = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (str != null && str.trim().length() > 0) {
phoneNum.add(str);
}
}
}
cursor.close();
textView.setText(phoneNum.get(0));
return phoneNum;
}
private void retrieveContactName(TextView textView, long contactId) {
String contactName = null;
Cursor cursor = context.getContentResolver().query(Contacts.CONTENT_URI, new String[] { ContactsContract.Contacts.DISPLAY_NAME },
ContactsContract.Contacts._ID + " = ?", new String[] { String.valueOf(contactId) }, null);
if (cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
cursor.close();
textView.setText(contactName);
}