4. Load Contact Photo

When query contacts, we can obtain a PHOTO_ID at the same time. By that ID, we can load the photo bitmap for drawing:
private static Bitmap loadContactPhoto(Context context, long photoId, BitmapFactory.Options options) {
    Cursor photoCursor = null;
    Bitmap photoBm = null;
    try {
        photoCursor = context.getContentResolver().query(ContentUris.withAppendedId(ContactsContract.Data.CONTENT_URI, photoId), new String[] { Photo.PHOTO }, null, null, null);

        if (photoCursor != null && photoCursor.moveToFirst() && !photoCursor.isNull(0)) {
            byte[] photoData = photoCursor.getBlob(0);
            photoBm = BitmapFactory.decodeByteArray(photoData, 0, photoData.length, options);
    } finally {
        if (photoCursor != null) {
    return photoBm;

Since android is commonly running on mobile devices, where to store the photo bitmaps is a serious question. For me, I use a SoftReference to store it. Below are the java doc for SoftReference.


Implements a soft reference, which is the least-weak of the three types of references. Once the garbage collector has decided that an object obj is softly-reachable, the following may happen, either immediately or at a later point:
  • A set ref of references is determined. ref contains the following elements:
    • All soft references pointing to obj.
    • All soft references pointing to objects from which obj is strongly reachable.
  • All references in ref are atomically cleared.
  • At the same time or some time in the future, all references in ref will be enqueued with their corresponding reference queues, if any.
The system may decide not to clear and enqueue soft references until a later time, yet all SoftReferences pointing to softly reachable objects are guaranteed to be cleared before the VM will throw an OutOfMemoryError. Soft references are useful for caches that should automatically have their entries removed once they are not referenced any more (from outside), and there is a need for memory. The difference between a SoftReferenceand a WeakReference is the point of time at which the decision is made to clear and enqueue the reference:
  • SoftReference should be cleared and enqueued as late as possible, that is, in case the VM is in danger of running out of memory.
  • WeakReference may be cleared and enqueued as soon as is known to be weakly-referenced.

There is a bug in android to prevent us to retrieve the contact photo (almost all missing contact photos are facebook porfile photo). To solve this, we must sign the APK by the shared cert and force the app running in shared-uid.