Get contact photo in Android (API 8) using LOOKUP_URI - android

I'm trying to get a contact image using its lookup URI.
I succeed getting the DISPLAY_NAME using this code:
Cursor c = context.getContentResolver().query(contactLookupUri,
new String[] { ContactsContract.Contacts.DISPLAY_NAME }, null,
null, null);
But I didn't find a way to get the photo. The Photo.PHOTO option is not valid for the API I'm using, and trying to get it using an inputStream didn't work as well (perhaps I did something wrong there):
InputStream input = ContactsContract.Contacts
.openContactPhotoInputStream(context.getContentResolver(),
contactUri);
Thanks,
Yoel

Eventually I solved it by getting the contact ID and using an inputStream:
public static Uri getContactLookupUri(String contactLookupKey) {
return Uri.withAppendedPath(
ContactsContract.Contacts.CONTENT_LOOKUP_URI, contactLookupKey);
}
public static Bitmap getContactImage(Context context, String contactLookupKey) {
long contactId;
try {
Uri contactLookupUri = getContactLookupUri(contactLookupKey);
Cursor c = context.getContentResolver().query(contactLookupUri,
new String[] { ContactsContract.Contacts._ID }, null, null,
null);
try {
if (c == null || c.moveToFirst() == false) {
return null;
}
contactId = c.getLong(0);
} finally {
c.close();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
InputStream input = ContactsContract.Contacts
.openContactPhotoInputStream(context.getContentResolver(),
contactUri);
if (input != null) {
return BitmapFactory.decodeStream(input);
} else {
return null;
}
}

The below function return the image uri of your contact_id
/**
* #return the photo URI
*/
public Uri getPhotoUri() {
try {
Cursor cur = this.ctx.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID + "=" + this.getId() + " AND "
+ ContactsContract.Data.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null,
null);
if (cur != null) {
if (!cur.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long
.parseLong(getId()));
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
Also refer this LINK

Related

Android - Get Contact Photo from phone number

how can I get contact photo from a contact's address (phone number)?
public static Bitmap retrieveContactPhoto(Context context, String number) {
ContentResolver contentResolver = context.getContentResolver();
String contactId = null;
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID};
Cursor cursor =
contentResolver.query(
uri,
projection,
null,
null,
null);
if (cursor != null) {
while (cursor.moveToNext()) {
contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
cursor.close();
}
Bitmap photo = BitmapFactory.decodeResource(context.getResources(),
R.drawable.default_image);
try {
if(contactId != null) {
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(contactId)));
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream);
}
assert inputStream != null;
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return photo;
}
I think this vesion works better in all android versions :
public Bitmap getContactsDetails(String address) {
Bitmap bp = BitmapFactory.decodeResource(context.getResources(),
R.drawable.contact_default_picture);
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
// querying contact data store
Cursor phones = context.getContentResolver().query(contactUri, null, null, null, null);
while (phones.moveToNext()) {
String image_uri = phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (image_uri != null) {
try {
bp = MediaStore.Images.Media
.getBitmap(context.getContentResolver(),
Uri.parse(image_uri));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return bp;
}
Call this method to get all contact information.
public void readContacts() {
StringBuffer sb = new StringBuffer();
sb.append("......Contact Details.....");
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
String phone = null;
String emailContact = null;
String emailType = null;
String image_uri = "";
Bitmap bitmap = 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));
image_uri = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
System.out.println("name : " + name + ", ID : " + id);
sb.append("\n Contact Name:" + name);
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
phone = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
sb.append("\n Phone number:" + phone);
System.out.println("phone" + phone);
}
pCur.close();
Cursor emailCur = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (emailCur.moveToNext()) {
emailContact = emailCur
.getString(emailCur
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
emailType = emailCur
.getString(emailCur
.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
sb.append("\nEmail:" + emailContact + "Email type:" + emailType);
System.out.println("Email " + emailContact
+ " Email Type : " + emailType);
}
emailCur.close();
}
if (image_uri != null) {
System.out.println(Uri.parse(image_uri));
try {
bitmap = MediaStore.Images.Media
.getBitmap(this.getContentResolver(),
Uri.parse(image_uri));
sb.append("\n Image in Bitmap:" + bitmap);
System.out.println(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sb.append("\n........................................");
}
textDetail.setText(sb);
}
}
You can use the column below to get the contacts photo uri, ContactsContract.CommonDataKinds.Phone.PHOTO_URI.
This is the function:
public static Bitmap getContactsDetails(String address) {
Bitmap bp = BitmapFactory.decodeResource(context.getResources(),
R.drawable.default_contact_photo);
String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " = '" + address + "'";
Cursor phones = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, selection,
null, null);
while (phones.moveToNext()) {
String image_uri = phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (image_uri != null) {
try {
bp = MediaStore.Images.Media
.getBitmap(context.getContentResolver(),
Uri.parse(image_uri));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return bp;
}
You can make some changes if you want to get Retrieving the larger photo
public Bitmap retrieveContactPhoto(Context context, String number) {
ContentResolver contentResolver = context.getContentResolver();
String contactId = null;
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID};
Cursor cursor =
contentResolver.query(
uri,
projection,
null,
null,
null);
if (cursor != null) {
while (cursor.moveToNext()) {
contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
cursor.close();
}
Bitmap photo = BitmapFactory.decodeResource(context.getResources(),
R.mipmap.popup);
try {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.valueOf(contactId));
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
AssetFileDescriptor fd =
getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
InputStream inputStream=fd.createInputStream();
if (inputStream != null) {
photo = BitmapFactory.decodeStream(inputStream);
}
assert inputStream != null;
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return photo;
}
for Retrieving the thumbnail-sized photo
public InputStream openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return new ByteArrayInputStream(data);
}
}
} finally {
cursor.close();
}
return null;
}
for more detail:
Click Here

Getting contact details takes too long in Android

I am trying to get id, firstName, lastName, fullName and photo from contacts. I used the following code for that,
but it takes too long to fetch data, at least 10 seconds. I used this code on thread so my activity won't freeze
but it takes too long to get all the data.
String[] projection = new String[] {ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME_ALTERNATIVE,
ContactsContract.Contacts.DISPLAY_NAME,
};
Cursor cursor = getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, projection, null,
null, null);
cursor.moveToFirst();
if (cursor.getCount() > 0) {
do {
try {
contactId = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
Uri contactUri = ContentUris.withAppendedId(
Contacts.CONTENT_URI,
Long.parseLong(contactId));
Uri dataUri = Uri.withAppendedPath(contactUri,
Contacts.Data.CONTENT_DIRECTORY);
Cursor phones = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = " + contactId,
null, null);
if (phones.getCount() > 0) {
ContactClass info = new ContactClass();
info.setid(contactId);
try {
Cursor nameCursor =
getContentResolver()
.query(dataUri,
null,
Data.MIMETYPE + "=?",
new String[] { StructuredName.CONTENT_ITEM_TYPE },
null);
nameCursor.moveToFirst();
do {
String firstName = nameCursor
.getString(nameCursor
.getColumnIndex(Data.DATA2));
String lastName = "";
String displayname = cursor
.getString(cursor
.getColumnIndex(Contacts.DISPLAY_NAME_ALTERNATIVE));
if (!firstName.equals(displayname)) {
lastName = nameCursor
.getString(nameCursor
.getColumnIndex(Data.DATA3));
}
// check lastName Value
if (firstName.equals(null)
&& lastName.equals(null)) {
info.setfirstname("unknown name");
} else if (firstName.equals(null)) {
info.setlastname(lastName);
} else if (lastName.equals(null)) {
info.setfirstname(firstName);
} else {
info.setfirstname(firstName);
info.setlastname(lastName);
}
} while (nameCursor.moveToNext());
nameCursor.close();
info.setphoto(retrieveContactPhoto(contactId));
contactinfo.add(info);
} catch (Exception e) {
}
}
phones.close();
}
catch (Exception t) {
}
} while (cursor.moveToNext());
cursor.close();
retrieveContactPhoto():
private String retrieveContactPhoto(String contactID) {
Uri photoUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
Long.parseLong(contactID));
final Cursor image = getContentResolver().query(photoUri,
PHOTO_ID_PROJECTION, null, null,
ContactsContract.Contacts._ID + " ASC");
try {
Integer thumbnailId = null;
if (image.moveToFirst()) {
thumbnailId = image.getInt(image
.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
Uri uri = ContentUris.withAppendedId(
ContactsContract.Data.CONTENT_URI, thumbnailId);
image.close();
if (uri.toString().equals(
"content://com.android.contacts/data/0"))
return null;
return uri.toString();
}
} finally {
image.close();
}
return null;
}
What do you recommend I should do to improve the perfomance of the above code?
i try this code to fetch my contact
try {
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != '' ))";
Cursor c = cntx.getContentResolver().query(Contacts.CONTENT_URI, CONTACTS_SUMMARY_PROJECTION, select,
null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
for(int i=0;i<c.getCount();i++)
{
// contactWrap.clear();
try {
contactId = 0;
String hasPhone = "";
display_name = "";
phoneNumber = "";
c.moveToPosition(i);
contactId = c.getLong(0);
display_name = c.getString(1);
hasPhone = c.getString(7);
if (hasPhone.equalsIgnoreCase("1"))
hasPhone = "true";
else
hasPhone = "false" ;
if (Boolean.parseBoolean(hasPhone))
{
Cursor phones = cntx.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null);
while (phones.moveToNext())
{
int indexPhoneType = phones.getColumnIndexOrThrow(Phone.TYPE);
String phoneType = phones.getString(indexPhoneType);
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String lookupKey = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
contactWrap.add(new ContactsWrapper(contactId, display_name, phoneNumber,lookupKey,false,color_string));
}
// map.put(contactId, new ArrayList<ContactsWrapper>(contactWrap));
phones.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
ohk u can take contactID from this cursor or your code now this is my method which will give u contact photo just pass contact ID in it
public InputStream openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return new ByteArrayInputStream(data);
}
}
} finally {
cursor.close();
}
return null;
}
Hope this will help u Best of luck dude

MemoryFile.finalize() called while ashmem still open - How to deal with it - Android

I have seen questions at SO regarding the same question, but none of them has an accepted answer.
What exactly is the error informing? Why does this occur?
I have few Cursors in my application, and I did close them, after their work is done. But the error still shows up. What could be the reason?
Here is the code :::
private String fetchContactIdFromPhoneNumber(String phoneNumber) {
// TODO Auto-generated method stub
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNumber));
Cursor cFetch = getContentResolver().query(uri,
new String[] { PhoneLookup.DISPLAY_NAME, PhoneLookup._ID },
null, null, null);
String contactId = "";
if (cFetch.moveToFirst()) {
cFetch.moveToFirst();
contactId = cFetch.getString(cFetch
.getColumnIndex(PhoneLookup._ID));
}
//System.out.println(contactId);
if(cFetch != null)
{
cFetch.close();
}
return contactId;
}
public Uri getPhotoUri(long contactId) {
ContentResolver contentResolver = getContentResolver();
Cursor cursor;
try {
cursor = contentResolver
.query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ contactId
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
if(cursor != null)
{
cursor.close();
}
Uri person = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
return Uri.withAppendedPath(person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
}
This is the code where I use cursors. I have also a contentresolver object. Should I close that as well?
And finally, what is the impact on this error on the application, because, it doesn't seem to interrupt the application's execution.

Get photo uri android 2.3.7 and android 4

i'm having some trouble about gettin photo uri between android 2.x and 4.x
The following code works perfectly on 2.x but not for 4.x
public static Uri getPhotoURIFromAddress(Context activity, String address) {
String contactId = fetchContactIdFromPhoneNumber(address,activity);
//Se non trovo il contatto il rubrica
if(contactId.equals("0")){
return null;
}
ContentResolver contentResolver = activity.getContentResolver();
try {
Cursor cursor = contentResolver
.query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ contactId
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
Log.i("No photo","No photo");
return null; // no photo
}
} else {
return null; // error in cursor process
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
How i can intregate working code for 4.x ?? Thanks

How to use "lookupKey" to get Contact Image?

I have lookupkeys for contact, now I want to obtain Contact Images as Bitmap/InputStream using these lookupkeys. Android documentation helps getting Images but with contacts id not lookupkey.
public InputStream openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return new ByteArrayInputStream(data);
}
}
} finally {
cursor.close();
}
return null;
}
Running from pillar to post but no help. Thanks
Edit Dated 04-09-2012
Tried as suggested by #Sreejith Krishnan R but received the following exceptions in logcat
09-04 03:16:26.359: E/AndroidRuntime(24008): java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/lookup/0r272-382C544E2C562C382C4E582C42.2649i11.1987r6285-382C544E2C562C382C4E582C42.1987r6440-382C544E2C562C382C4E582C42.2829r6475-382C544E2C562C382C4E582C42/photo, calling user: com.xyz, calling package:com.xyz
09-04 03:16:26.359: E/AndroidRuntime(24008): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:144)
09-04 03:16:26.359: E/AndroidRuntime(24008): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114)
[Updated]
Now this can be used since API level 5
public Bitmap getAvatar(Context context, String lookupKey){
Uri uri = getDataUri(context, lookupKey);
if (uri == null){
return null;
}
Cursor cursor = context.getContentResolver().query(
uri,
new String[] {ContactsContract.Data.DATA15},
null,
null,
null
);
if (cursor == null){
return null;
}
try{
if (cursor.moveToFirst()){
byte [] bytes = cursor.getBlob(0);
InputStream inputStream = new ByteArrayInputStream(bytes);
return BitmapFactory.decodeStream(inputStream);
}
} finally {
cursor.close();
}
return null;
}
public Uri getDataUri(Context context, String lookupKey){
Cursor cursor = context.getContentResolver().query(
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey),
new String[] {ContactsContract.Contacts.PHOTO_ID},
null,
null,
null
);
if (cursor == null){
return null;
}
try {
if (cursor.moveToFirst()){
long id = cursor.getLong(0);
/**http://developer.android.com/reference/android/provider/ContactsContract.ContactsColumns.html#PHOTO_ID
* If PHOTO_ID is null, consult PHOTO_URI or PHOTO_THUMBNAIL_URI,
* which is a more generic mechanism for referencing the contact photo,
* especially for contacts returned by non-local directories (see ContactsContract.Directory).
*/
if (id == 0){
if (Build.VERSION.SDK_INT < 11){
return null;
}
return getPhotoThumbnailUri(context, lookupKey);
}
return ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
}
} finally {
cursor.close();
}
return null;
}
//Available only for API level 11+
public Uri getPhotoThumbnailUri(Context context, String lookupKey){
Cursor cursor = context.getContentResolver().query(
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey),
new String[] {ContactsContract.Contacts.PHOTO_THUMBNAIL_URI},
null,
null,
null
);
if (cursor == null){
return null;
}
try{
if (cursor.moveToFirst()){
return Uri.parse(cursor.getString(0));
}
} finally {
cursor.close();
}
return null;
}

Categories

Resources