title: Android - how to get contact photo from PHOTO_THUMBNAIL_URI
body: <p>In my Android app (Android 4+) I want to pick a phone number and the corresponding profile photo from Contacts. After going though the documentation and through SO questions, if tried many suggestions and different approaches. The only one I could get reliably to work is sketched below.</p>
  
  <p>The question I have is about the method <strong>getContactPhoto</strong>. Why is it necessary to strip <strong><em>"/photo"</em></strong> from the string value stored in column <em>ContactsContract.Contacts.PHOTO_THUMBNAIL_URI</em> ? If I don't do that, the app will crash (if I don't catch the exception). I did not see anywhere documented that <em>"/phone"</em> had to be removed, (just trial and error) and one would imagine the URI as returned would not require manual patching. It seems to work OK this way on some Android 4, 5, and 7 devices, but I'd like to understand why this is required.</p>
  
  <pre><code>    private void selectPhoneContact() {
          Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
          intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
          if (intent.resolveActivity(getPackageManager()) != null)
              startActivityForResult(intent, usePhone ? ACTIVITY_RESULT_PICK_PHONE_CONTACT : ACTIVITY_RESULT_PICK_EMAIL_CONTACT);
      }
  
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          case ACTIVITY_RESULT_PICK_PHONE_CONTACT:
              Uri contactUri = data.getData();
              if (contactUri != null) {
                  try {
                      String[] projection = new String[]{ContactsContract.Contacts._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
                      Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
                      if (cursor != null) {
                          try {
                              if (cursor.moveToFirst()) {
                                  String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(valueColumn));
                                  Bitmap profileImage = getContactPhoto(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
                              }
                          }
                          finally {
                              cursor.close();
                          }
                      }
                  }
                  catch (Exception e) {
                      e.printStackTrace();
                  }
              }
              break;
          }
      }
  
      private Bitmap getContactPhoto(String thumbnailUri) throw IOException {
          if (thumbnailUri == null)
              return null;
          if (thumbnailUri.endsWith("/photo"))
              thumbnailUri = thumbnailUri.substring(0, thumbnailUri.length() - 6); // remove "/photo"
          Uri photoUri = Uri.parse(thumbnailUri);
          InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), photoUri);
          if (inputStream == null) 
              return null;
          try {
              return BitmapFactory.decodeStream(inputStream);
          }
          finally {
              inputStream.close();
          }
      }
  </code></pre>
  
  <p>As suggested by pskink I created an alternative based on how a SimpleCursorAdapter loads the bitmap in an ImageView. This essentially comes down to getContactPhoto2 as listed below. THis also works OK and I'll use that instead.</p>
  
  <pre><code>private Bitmap getContactPhoto2(String thumbnailUri) throws Exception {
      InputStream stream = null;
      try {
          stream = getContentResolver().openInputStream(Uri.parse(thumbnailUri));
          Bitmap  bm = BitmapFactory.decodeResourceStream(getResources(), null, stream, null, null);
          if (bm != null)
              Log.d("Contacts photo", String.format("Bitmap: %d x %d", bm.getWidth(), bm.getHeight()));
          return bm;
      } finally {
          if (stream != null)
              stream.close();
      }
  }
  </code></pre>