Getting contact photo - android

I am having a problem getting a contact photo, the kind you see in the messaging app and new gmail notification. I have looked at a few example codes but nothing has worked for me, this is what I currently have
this should get the photo uri and turn it into a bitmap image to use or at least it seems
public static Bitmap getContactImage(long id,Context context){
InputStream input = getPhoto(id,context);
if(input == null){
return null;
}
return BitmapFactory.decodeStream(input);
}
public static InputStream getPhoto(long contactId,Context context){
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
InputStream in = null;
try{
in = context.getContentResolver().openInputStream(photoUri);
}catch(FileNotFoundException e){
Log.d(TAG, e.toString());
}
return in;
}
and this is how I call
long contactID = 0;
Bitmap image = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_contact_picture);
Cursor contact = context.getContentResolver().query(Data.CONTENT_URI,new String[] {Data.CONTACT_ID},Email.ADDRESS + "='" + from + "'",null,null);
if(contact.moveToFirst() && contact != null){
contactID = contact.getLong(0);
image = getContactImage(contactID,context);
}
I get the contact id fine (checked by searching the number for the person querying against) but then it does not find the contact photo. I know there is a photo because I am testing it against myself to make sure and I have a contact photo so I dont know what else I should do.
I always find navigating the contact provider very troublesome because there is so much to it.

I got it, I did a query against the RAW_CONTACT_ID with the MIMETYPE and that gave me the photo I was looking for
Cursor p = context.getContentResolver().query(Data.CONTENT_URI,new String[] {Photo.PHOTO},
Data.RAW_CONTACT_ID + "=" + contactId + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE+"'"
,null,null);

You're doing it wrong.
First, get an ID of the photo from the PHOTO_ID column of ContactsContract.Contacts table. Next, retrieve a byte array from PHOTO column (which is actually alias to DATA15) from ContactsContract.Data by ID you got in previous step. And, finally, decode that byte array using BitmapFactory to get a bitmap.
Here are docs about this.

This works for me.
//Querying for all contacts(Apply selection parameter in query to get a specific contact)
Uri contacts = ContactsContract.Contacts.CONTENT_URI;
cur = null;
cur = Main.context.getContentResolver().query(contacts, null, null,
null, null);
int contactIdIndex = cur.getColumnIndex(ContactsContract.PhoneLookup._ID);
int contactId = cur.getInt(contactIdIndex);
// Photo
Uri contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = cr
.query(
photoUri,
new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO },
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
_conEntry.setPhoto(data);
//Data is the photo bytes for you
}
if (cursor != null)
cursor.close();

Related

How to handle the Contact URi in android

I.m new to Android Contact's, I wanted to return a contact id/ contact from below URi:
content://com.android.contacts/contacts/lookup/encoded?directory=2147483647#{\"display_name\":\"\u202A9500249707\u202C\",\"display_name_source\":20,\"vnd.android.cursor.item\\/contact\":{\"vnd.android.cursor.item\\/phone_v2\":[{\"data1\":\"123456789\"}
]}}
which is start with encoded?directory=2147483647..
can any one suggestion me here!!
In order to fetch the contact from the external storage of the phone, we have to understand about content Resolver,Cursor which you can learn on the android documentation.As you have asked in question, to handle the contact and it's related data, we can use following code.
Uri contactUri = data.getData();
Cursor cursor = null;
try {
String phoneNo = null;
cursor = getContentResolver()
.query(contactUri, null, null, null, null);
if (cursor.getCount() == 0) return;
cursor.moveToFirst();
String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
int phoneIndex = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER);
phoneNo = cursor.getString(phoneIndex);
} finally {
cursor.close();
}
From this sample code,We can extract the necessary data using content Resolver and content provider.
But first, we have to pass content uri through intent as below to use the above code.
pickContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);

How to obtain the contact Uri directly with contact creation

my app creates new contacts with ContentProviderOperation. The problem is, I need a reference to the new contact because I need some information of it to display it in a listview and go with intent into the contact app to the contact.
The best thing would be the ID, but I´ve read that it might change during operations on the database, which won´t be helpful to me.
Now I thought, the Uri might be the best thing, because I could later retrieve the contactID or lookup key.
How do I get the Uri directly after calling applyBatch() ?
EDIT:
Here is a solution, but not really a good one.
He is putting a randomly generated token into each contact, then he makes a new query with it.
I want neither put some extra data into the contacts, nor starting a second query. But if there is no other possibility I´ll do it that way.
simply call
private String retrieveContactId(String phoneNo) {
try {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNo));
String[] projection = new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME };
String selection = null;
String[] selectionArgs = null;
String sortOrder = ContactsContract.PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getApplicationContext().getApplicationContext().getContentResolver();
String contactId = null;
if (cr != null) {
Cursor resultCur = cr.query(uri, projection, selection, selectionArgs, sortOrder);
if (resultCur != null) {
while (resultCur.moveToNext()) {
contactId = resultCur.getString(resultCur.getColumnIndex(ContactsContract.PhoneLookup._ID));
Log.e("Info Incoming", "Contact Id : " + contactId);
return contactId;
}
resultCur.close();
}
}
} catch (Exception sfg) {
Log.e("Error", "Error in loadContactRecord : " + sfg.toString());
}
return null;
}
and for the uri
Uri contactUri = Contacts.getLookupUri(
Integer.valueOf(rawContactId), clookup);

How to get merged Contact's photo?

I am trying to figure out how to get the photo for a merged contact, to display in a QuickContactBadge. I've been searching and googling, and all the things I can find online say this is not possible if the contact's default image comes from a Facebook sync. However all the examples I find also reference Froyo or Gingerbread.
Is there still no way to do this in the ICS/JB age?
This answer seemed the most promising, but the comments seem to say it is hit or miss.
None of the things I've found online have worked for me.
Here is the code I currently have:
public static Uri getContactPhotoUri(long ContactId) {
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, ContactId);
Uri photo = Uri.withAppendedPath(person, Contacts.Photo.CONTENT_DIRECTORY);
Cursor cur = App.ContentResolver().query(
Data.CONTENT_URI,
new String[] { Data._ID },
ContactsContract.Data.CONTACT_ID
+ "="
+ ContactId
+ " AND "
+ Data.MIMETYPE
+ "='"
+ Photo.CONTENT_ITEM_TYPE
+ "'", null, Data.IS_PRIMARY + " DESC");
Uri rv = null;
rv = (cur == null || !cur.moveToFirst())? null: photo;
if (cur != null) cur.close();
return rv;
}
It shows the image properly for contacts where the image comes from the google contact.
The image does not show properly for contacts where the primary image comes from Facebook.
Is there REALLY, still, no reliable way to get the default image for a contact regardless of where the image comes from?
EDIT (01/18/2013): I've also tried querying the PHOTO_URI and PHOTO_THUMBNAIL_URI as follows, with the same results.
public static String[] GroupMembersProjection = new String[] {
Contacts._ID,
Contacts.LOOKUP_KEY,
Contacts.DISPLAY_NAME_PRIMARY,
Contacts.PHOTO_THUMBNAIL_URI
};
public static Cursor getGroupMembers(int groupid, String sort) {
String ord;
if (sort.equals("A")) { ord = Contacts.DISPLAY_NAME_PRIMARY; }
else { ord = Contacts.TIMES_CONTACTED + " DESC"; /* SORT = "U"; DEFAULT */ }
ContentResolver cr = App.ContentResolver();
Cursor contacts = cr.query(Data.CONTENT_URI,
GroupMembersProjection,
GroupMembership.GROUP_ROW_ID + "=" + groupid, null, ord);
return contacts;
}
Additionally, I tried querying PHOTO_ID instead of the PHOTO_URI fields, and then using the following code to get the URI manually and use that for the image, but this also yields the same results, showing google images, but not Facebook ones.
Uri puri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photoid);

Loading contact picture via LOOKUP_KEY and openContactPhotoInputStream convenience method

I'm modifying my app to store information on contacts using LOOKUP_KEY instead of _ID as suggested by the API docs. The only problem I'm having is that I'm no longer able to load the contact's photo.
The problematic code is this one:
InputStream s = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), contactUri);
This is returning the following error: java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/lookup/1424i118.2312i1220228108/photo
The contactUri that I am using as argument is acquired by the following: Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, contact_key);
and in this example, contact_key is 1424i118.2312i1220228108
Based on the API docs, this helper method should work with both CONTENT_URI or CONTENT_LOOKUP_URI, which I am using.
Any ideas? Thanks.
For anyone with a similar problem, this did the trick for me:
public Bitmap getPhoto(Uri uri){
Bitmap photoBitmap = null;
String[] projection = new String[] { ContactsContract.Contacts.PHOTO_ID };
Cursor cc = getContentResolver().query(uri, projection, null, null, null);
if(cc.moveToFirst()) {
final String photoId = cc.getString(cc.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
if(photoId != null) {
final Cursor photo = managedQuery(
Data.CONTENT_URI,
new String[] {Photo.PHOTO},
Data._ID + "=?",
new String[] {photoId},
null
);
// Convert photo blob to a bitmap
if(photo.moveToFirst()) {
byte[] photoBlob = photo.getBlob(photo.getColumnIndex(Photo.PHOTO));
photoBitmap = BitmapFactory.decodeByteArray(photoBlob, 0, photoBlob.length);
}
photo.close();
}
}
cc.close();
return photoBitmap;
}

Obtaining thumbnails for images in android using ContentResolver and Cursor

The following is my code for obtaining a thumbnail of a given image.
As of now, the exception that I'm getting is 'Cursor out of bounds'
I think that may be because I am not appending the image URL anywhere. I'm a little confused as to where to do that.
So 2 questions:
1. Where do I use the image URL of which I want to obtain a thumbnail
2. The for loop which is supposed to print column names prints nothing except the first statement 'COLUMN NAMES'
//get the corresponding thumbnail
String lastImageTakenPath = MyActivity.this.savedInstanceStateVariable.getString("lastImageTaken");
System.out.println("previous image is "+ lastImageTakenPath);
ContentResolver cr = getContentResolver();
if(cr != null){
String[] projection = { MediaStore.Images.Media._ID };
Cursor cursor = managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,projection,null,null,null);
//Cursor cursor = cr.query(lastImageTakenURI, null, null, null, null);
//Activity.startManagingCursor(cursor);
if(cursor != null){
String[] columnNames = cursor.getColumnNames();
System.out.println("COLUMN NAMES");
for(int i=0;i<columnNames.length; i++){
System.out.println(columnNames[i]);
}
/* 1. get the id of the image
* 2. use this id in the call, getThumbnails on MediaStore.Images.Thumbnails to obtain the
thumbnail
3.set the imageview's src to this thumbnail */
int imageID = cursor.getInt( cursor.getColumnIndex(MediaStore.Images.Media._ID) );
Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID) );
// Get original image ID
String url = uri.toString();
int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
// Get (or create upon demand) the micro thumbnail for the original image.
thumbnailLastImage = MediaStore.Images.Thumbnails.getThumbnail(cr, originalImageId, MediaStore.Images.Thumbnails.MICRO_KIND,null);
thumbnailImage.setImageBitmap(thumbnailLastImage);
}
else{
System.out.println("Cursor is NULL");
}
}
else{
Log.d(TAG,"ContentResolver is NULL");
}
I believe your test of if(cursor != null) is incorrect or at least insufficient. If the result of the query returns no thumbnails then you will still get a cursor where cursor.getCount() == 0 you may want to use that as your test.

Categories

Resources