How can I retrieve the picture of the contact?

Asked 2 years ago, Updated 2 years ago, 28 views

I'm having a hard time retrieving pictures of contacts on Android. I tried to google it, but I couldn't find the relevant data. Does anyone have an example of querying a contact to retrieve a photo?

startActivityForResult(new Intent(Intent.ACTION_PICK,ContactsContract.CommonDataKinds.Phone.CONTENT_URI),PICK_CONTACT_REQUEST)

The contactUri retrieved from the activity result using the above code is as follows.

content://com.android.contacts/data/1557

The loadContact(..) function that loads contacts works fine, but when you call the getPhoto() function that loads pictures, a null value appears in the picture InputStream. The confusing thing is that the URI value is different. Contact PhotoUri is as follows.

content://com.android.contacts/contacts/1557

Please refer to the notes in the code below.

class ContactAccessor {

/**
 * A function that retrieves contact information
 */
public ContactInfo loadContact(ContentResolver contentResolver, Uri contactUri) {

    //contactUri --> content://com.android.contacts/data/1557

    ContactInfo contactInfo = new ContactInfo();

    // Calling up names for a specific 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; // <-- Return contact information
}

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); // <-- This part always returns 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;
    }

}
}

I'm sure I made a mistake somewhere here, but I can't find the problem. Thank you.

android contactscontract

2022-09-22 21:36

1 Answers

I've seen a lot of questions and answers about the thumbnail issue, but I've only seen a couple of ways to solve it, and I haven't seen a good solution.

The classes below call up Context, QuickContactBadge, and phone numbers, if any images are available for a particular phone number.

The classes are as follows.

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();
    }

}

}

And below is how to use it in the activity :

String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(this, badge, phoneNumber).addThumbnail();

It's a little different if you use it in a fragment :

String phoneNumber = "...";
QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.friend);
new QuickContactHelper(getActivity(), badge, phoneNumber).addThumbnail();

Of course, to use this code more efficiently, you need to modify it somewhat. For example, if a questioner wants to organize a message timeline, he or she would rather reuse the same picture file on all badges that correspond to the same phone number than recall a new picture file from time to time. However, the purpose of this answer is to provide a solution that users can complete and use in an original way to make a point more clearly. This solution was built and tested in an Android 4.0 environment, and was also tested in 4.1.


2022-09-22 21:36

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.