¿Cómo cargo una foto de contacto?
-
24-09-2019 - |
Pregunta
Tengo problemas para cargar una foto para un contacto en Android. He buscado en Google una respuesta, pero hasta ahora he vuelto vacío. ¿Alguien tiene un ejemplo de consulta para un contacto y luego cargando la foto?
Entonces, dado un contacturi que proviene de un resultado de actividad llamado usando
startActivityForResult(new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI),PICK_CONTACT_REQUEST)
es:
Contenido: //com.android.contacts/data/1557
La carga de carga (..) funciona bien. Sin embargo, cuando llamo al método GetPhoto (...), obtengo un valor nulo para el Foto InputStream. También es confuso porque los valores de URI son diferentes. El ContactPhotouri evalúa:
Contenido: //com.android.contacts/contacts/1557
Vea los comentarios en línea en el código a continuación.
class ContactAccessor {
/**
* Retrieves the contact information.
*/
public ContactInfo loadContact(ContentResolver contentResolver, Uri contactUri) {
//contactUri --> content://com.android.contacts/data/1557
ContactInfo contactInfo = new ContactInfo();
// Load the display name for the specified person
Cursor cursor = contentResolver.query(contactUri,
new String[]{Contacts._ID,
Contacts.DISPLAY_NAME,
Phone.NUMBER,
Contacts.PHOTO_ID}, null, null, null);
try {
if (cursor.moveToFirst()) {
contactInfo.setId(cursor.getLong(0));
contactInfo.setDisplayName(cursor.getString(1));
contactInfo.setPhoneNumber(cursor.getString(2));
}
} finally {
cursor.close();
}
return contactInfo; // <-- returns info for contact
}
public Bitmap getPhoto(ContentResolver contentResolver, Long contactId) {
Uri contactPhotoUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
// contactPhotoUri --> content://com.android.contacts/contacts/1557
InputStream photoDataStream = Contacts.openContactPhotoInputStream(contentResolver,contactPhotoUri); // <-- always null
Bitmap photo = BitmapFactory.decodeStream(photoDataStream);
return photo;
}
public class ContactInfo {
private long id;
private String displayName;
private String phoneNumber;
private Uri photoUri;
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Uri getPhotoUri() {
return this.photoUri;
}
public void setPhotoUri(Uri photoUri) {
this.photoUri = photoUri;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
}
}
Claramente, estoy haciendo algo mal aquí, pero parece que no puedo descubrir cuál es el problema. Gracias.
Solución
Después de escanear las muchas preguntas y respuestas al problema de mostrar una miniatura, pensé que publicaría mi solución a este enigma en particular, ya que solo podía encontrar una pareja que funcionara y ninguna que proporcionara una buena solución enlatada para el desarrollador perezoso.
La siguiente clase toma un contexto, QuickContactBadge y un número de teléfono y adjuntará una imagen almacenada localmente a la insignia si hay una disponible para el número de teléfono especificado.
Aquí está la clase:
public final class QuickContactHelper {
private static final String[] PHOTO_ID_PROJECTION = new String[] {
ContactsContract.Contacts.PHOTO_ID
};
private static final String[] PHOTO_BITMAP_PROJECTION = new String[] {
ContactsContract.CommonDataKinds.Photo.PHOTO
};
private final QuickContactBadge badge;
private final String phoneNumber;
private final ContentResolver contentResolver;
public QuickContactHelper(final Context context, final QuickContactBadge badge, final String phoneNumber) {
this.badge = badge;
this.phoneNumber = phoneNumber;
contentResolver = context.getContentResolver();
}
public void addThumbnail() {
final Integer thumbnailId = fetchThumbnailId();
if (thumbnailId != null) {
final Bitmap thumbnail = fetchThumbnail(thumbnailId);
if (thumbnail != null) {
badge.setImageBitmap(thumbnail);
}
}
}
private Integer fetchThumbnailId() {
final Uri uri = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
final Cursor cursor = contentResolver.query(uri, PHOTO_ID_PROJECTION, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
try {
Integer thumbnailId = null;
if (cursor.moveToFirst()) {
thumbnailId = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
}
return thumbnailId;
}
finally {
cursor.close();
}
}
final Bitmap fetchThumbnail(final int thumbnailId) {
final Uri uri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, thumbnailId);
final Cursor cursor = contentResolver.query(uri, PHOTO_BITMAP_PROJECTION, null, null, null);
try {
Bitmap thumbnail = null;
if (cursor.moveToFirst()) {
final byte[] thumbnailBytes = cursor.getBlob(0);
if (thumbnailBytes != null) {
thumbnail = BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
}
}
return thumbnail;
}
finally {
cursor.close();
}
}
}
Y aquí hay un caso de uso típico dentro de una actividad:
String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(this, badge, phoneNumber).addThumbnail();
En un fragmento será ligeramente diferente:
String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(getActivity(), badge, phoneNumber).addThumbnail();
Ahora hay formas de ser más eficientes, por ejemplo, si está haciendo una línea de tiempo de mensajes, desea reutilizar el mismo objeto de mapa de bits para cada instancia de insignia para un número de teléfono dado en lugar de crear constantemente nuevas instancias de clase de ayuda y volver Recuperando el mapa de bits, pero mi propósito aquí era publicar una solución que se despoja al mínimo absoluto para mayor claridad, al mismo tiempo que proporciona una solución completa y utilizable de la caja. Esta solución se ha construido y probado en Andriod 4.0, y también probada en 4.1.
Otros consejos
Esto funciona para mí:
public static Bitmap loadContactPhoto(ContentResolver cr, long id) {
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
if (input == null) {
return null;
}
return BitmapFactory.decodeStream(input);
}
Chicos, pasé muchas horas intentando resolver esto. Aquí hay un método que creé que le dará su foto de Facebook por número de teléfono (sin guiones). Puede, por supuesto, modificarlo en consecuencia:
public Bitmap getFacebookPhoto(String phoneNumber) {
Uri phoneUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Uri photoUri = null;
ContentResolver cr = this.getContentResolver();
Cursor contact = cr.query(phoneUri,
new String[] { ContactsContract.Contacts._ID }, null, null, null);
if (contact.moveToFirst()) {
long userId = contact.getLong(contact.getColumnIndex(ContactsContract.Contacts._ID));
photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, userId);
}
else {
Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
if (photoUri != null) {
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(
cr, photoUri);
if (input != null) {
return BitmapFactory.decodeStream(input);
}
} else {
Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
Bitmap defaultPhoto = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
Después de muchas noches de depuración, descubro que el mejor enfoque es usar el contact id
y si no usa el photo id
.
public static Bitmap loadContactPhoto(ContentResolver cr, long id,long photo_id)
{
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
if (input != null)
{
return BitmapFactory.decodeStream(input);
}
else
{
Log.d("PHOTO","first try failed to load photo");
}
byte[] photoBytes = null;
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photo_id);
Cursor c = cr.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
try
{
if (c.moveToFirst())
photoBytes = c.getBlob(0);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
c.close();
}
if (photoBytes != null)
return BitmapFactory.decodeByteArray(photoBytes,0,photoBytes.length);
else
Log.d("PHOTO","second try also failed");
return null;
}
El código probado en el emulador y el dispositivo Nexus S y parece funcionar.
Ninguno de estos enfoques funcionó para mí. Lo que funcionó fue:
String[] projection = new String[] {
ContactsContract.Contacts.PHOTO_ID, ///< the correct ID for photo retrieval in loadLocalContactPhotoBytes()
// ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
// ContactsContract.CommonDataKinds.Photo.PHOTO
};
ContentResolver cr = ctx.getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
// Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,
// new String[] {RawContacts._ID, RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME},
// new String[] {Contacts._ID},
projection, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
....
// El 'cursor' anterior se aprobó como argumento a continuación
private byte[] loadLocalContactPhotoBytes(ContentResolver cr, Cursor cursor, byte[] defaultPhotoBytes)
{
byte[] photoBytes = null;// = cursor.getBlob(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO));
// int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
// Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
// Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
Cursor c = cr.query(photoUri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
try
{
if (c.moveToFirst())
photoBytes = c.getBlob(0);
} catch (Exception e) {
// TODO: handle exception
Log.w(_TAG, e.toString());
} finally {
c.close();
}
photoBytes = photoBytes == null ? defaultPhotoBytes : photoBytes;
return photoBytes;
}
Solo para patadas copié la mayoría de las respuestas aquí en una sola clase para ver si alguno de ellos lograra obtener la miniatura de Facebook. No lo hicieron ... pero esto es lo que hice para salvarte haciendo lo mismo.
Muestra los resultados en un diálogo para facilitar.
Por favor tenga cuidado - No está optimizado y necesitará capturar errores y cerrar cursores, etc.:
Para comenzar la intención del selector de contacto:
private static final int SELECT_CONTACT = 1468;
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
contactPickerIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
try {
startActivityForResult(contactPickerIntent, SELECT_CONTACT);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
La devolución de llamada:
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case SELECT_CONTACT:
Uri contactURI = data.getData();
if (contactURI != null) {
String contactID = data.getData().getLastPathSegment().trim();
String contactName = ContactThumb.getDisplayName(getActivity(), contactURI);
if (contactName != null && !contactName.isEmpty() && contactID != null && !contactID.isEmpty()) {
final int THUMBNAIL_SIZE = 100;
Bitmap contactThumb = ContactThumb.loadContactPhoto(getActivity(), Long.valueOf(contactID));
if (contactThumb != null) {
final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
final int width = contactThumb.getWidth();
final int height = contactThumb.getHeight();
final int ratio = width / height;
final Bitmap resized = ThumbnailUtils.extractThumbnail(contactThumb, (THUMBNAIL_SIZE * ratio),
THUMBNAIL_SIZE);
Drawable icon = new BitmapDrawable(getActivity().getResources(), resized);
alert.setIcon(icon);
alert.setTitle("Contact details");
final TextView homeTV = new TextView(getActivity());
homeTV.setText(contactName + " : " + contactID);
homeTV.setTextSize(12);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
homeTV.setTextColor(Color.WHITE);
}
homeTV.setPadding(30, 2, 20, 10);
homeTV.setMovementMethod(LinkMovementMethod.getInstance());
alert.setView(homeTV);
alert.show();
} else {
Toast.makeText(getActivity(), "Photo null", Toast.LENGTH_SHORT).show();
}
}
}
break;
}
} else {
// cancelled or error
}
}
Los intentos de la tortura de contacto ....
import java.io.InputStream;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.util.Log;
public class ContactThumb {
private static final String TAG = "THUMB";
public static String getDisplayName(final Context ctx, final Uri contactURI) {
String cname = null;
try {
final String[] projection = new String[] { ContactsContract.Contacts.DISPLAY_NAME };
final Cursor cursor = ctx.getContentResolver().query(contactURI, projection, null, null, null);
if (cursor != null) {
try {
if (cursor.moveToFirst()) {
cname = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
} catch (final Exception e) {
e.printStackTrace();
}
return cname;
}
public static Bitmap loadContactPhoto(final Context ctx, final long contactId) {
final Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
final InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(), contactUri);
if (input != null) {
Log.i(TAG, "loadContactPhoto: input");
return BitmapFactory.decodeStream(input);
} else {
byte[] photoBytes = null;
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
final Cursor c = ctx.getContentResolver().query(photoUri,
new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO }, null, null, null);
try {
if (c.moveToFirst()) {
photoBytes = c.getBlob(0);
}
} catch (final Exception e) {
e.printStackTrace();
} finally {
c.close();
}
if (photoBytes != null) {
Log.i(TAG, "loadContactPhoto: photoBytes");
return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
} else {
Bitmap another = finalAttempt(ctx, contactId);
if (another != null) {
Log.i(TAG, "loadContactPhoto: another");
return another;
} else {
Log.i(TAG, "loadContactPhoto: might be returning default");
return getFacebookPhoto(ctx, getContactNumber(ctx, String.valueOf(contactId)));
}
}
}
}
public static String getContactNumber(final Context ctx, final String contactID) {
Cursor phones = null;
try {
phones = ctx.getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + " = " + contactID, null, null);
String cnum = null;
if (phones != null && phones.getCount() > 0) {
while (phones.moveToNext()) {
cnum = phones.getString(phones.getColumnIndex(Phone.NUMBER));
if (cnum != null && !cnum.isEmpty() && !cnum.contains("@")) {
Log.i(TAG, "getContactNumbers: : cnum: " + cnum);
try {
phones.close();
} catch (Exception e) {
e.printStackTrace();
}
return cnum;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Bitmap getFacebookPhoto(final Context ctx, String phoneNumber) {
Uri phoneUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Uri photoUri = null;
ContentResolver cr = ctx.getContentResolver();
Cursor contact = cr.query(phoneUri, new String[] { ContactsContract.Contacts._ID }, null, null, null);
if (contact.moveToFirst()) {
long userId = contact.getLong(contact.getColumnIndex(ContactsContract.Contacts._ID));
photoUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, userId);
} else {
Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
if (photoUri != null) {
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, photoUri);
if (input != null) {
return BitmapFactory.decodeStream(input);
}
} else {
Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
Bitmap defaultPhoto = BitmapFactory.decodeResource(ctx.getResources(), android.R.drawable.ic_menu_report_image);
return defaultPhoto;
}
public static Bitmap finalAttempt(final Context ctx, final long contactId) {
byte[] photoBytes = null;
String[] projection = new String[] { ContactsContract.Contacts.PHOTO_ID, ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER, };
ContentResolver cr = ctx.getContentResolver();
final Uri contactUri = ContentUris.withAppendedId(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, contactId);
Cursor cursor = cr.query(contactUri, projection, null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
Uri photoUri = ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, id);
Cursor c = cr.query(photoUri, new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO }, null, null, null);
try {
if (c.moveToFirst()) {
photoBytes = c.getBlob(0);
}
} catch (Exception e) {
} finally {
cursor.close();
c.close();
}
if (photoBytes != null) {
return BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
}
}
return null;
}
}
Si alguno de los métodos funciona para usted, ¡por favor vota la respuesta que he copiado y pegado el código!
Verifique este enlace para el Los desarrolladores de Android sugirieron la forma
Buena suerte
Parece que mi problema era porque los contactos en mi dispositivo se sincronizaron de Facebook y, por lo tanto, la foto no está disponible.
http://groups.google.com/group/android-developers/msg/be8d0cf3928e4b7f
La documentación de Android dice que deberíamos hacerlo de esta manera.
public Bitmap openPhoto(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = getContentResolver().query(photoUri,
new String[] {ContactsContract.Contacts.Photo.PHOTO}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return BitmapFactory.decodeStream(new ByteArrayInputStream(data));
}
}
} finally {
cursor.close();
}
return null;
}
ContactId significa:
getString(c.getColumnIndex(ContactsContract.Contacts._ID))
fuente: https://developer.android.com/reference/android/provider/contactscontract.contacts.photo.html
Código tomado:desarrollador.android.com
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;
}
Después de algunas investigaciones, encontré la solución en: Mostrando la insignia de contacto rápida
Mi código con algunas modificaciones menores, me funciona bien
public Bitmap loadContactPhoto(String name) {
String photoUri = null;
int thumbnailColumn;
ContentResolver cr = GlobalData.instance().getContext().getContentResolver();
String[] projection = new String[] { ContactsContract.Contacts._ID ,ContactsContract.Contacts.PHOTO_ID, ContactsContract.Contacts.PHOTO_URI, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, projection, ContactsContract.Contacts.DISPLAY_NAME + "='" + name + "'", null, null);
if (cursor.moveToFirst()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
thumbnailColumn = cursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI);
else
thumbnailColumn = cursor.getColumnIndex(PhoneLookup._ID);
photoUri = cursor.getString(thumbnailColumn);
if(photoUri != null)
return loadContactPhotoThumbnail(photoUri);
else
return null;
}
return null;
}
private Bitmap loadContactPhotoThumbnail(String photoData) {
AssetFileDescriptor afd = null;
try {
Uri thumbUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
thumbUri = Uri.parse(photoData);
} else {
final Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_URI, photoData);
thumbUri = Uri.withAppendedPath(contactUri, Photo.CONTENT_DIRECTORY);
}
afd = GlobalData.instance().getContext().getContentResolver().openAssetFileDescriptor(thumbUri, "r");
FileDescriptor fileDescriptor = afd.getFileDescriptor();
if (fileDescriptor != null)
return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, null);
} catch (FileNotFoundException e) {
} finally {
if (afd != null) {
try {
afd.close();
} catch (IOException e) {
}
}
}
return null;
}
Mira mi publicación:
https://stackoverflow.com/a/41445851/1733810
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;
}