title: Insert Contact (ContactsContract) via Intent with Image (Photo)
body: <p>There is many Q&amp;A threads, but none of them is providing real answer, or I couldn't find it.</p>
  
  <p>To ensure you, I've searched before asking:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/6446267/android-set-contact-photo-with-contactscontract-insert-intent">Android: set contact photo with ContactsContract insert intent</a> (invalid answer)</li>
  <li><a href="https://stackoverflow.com/questions/4459138/insert-contact-in-android-with-contactscontract">Insert contact in Android with ContactsContract</a> (accepted answer does not use Intent)</li>
  <li><a href="https://stackoverflow.com/questions/14278587/insert-a-new-contact-intent">Insert a new contact intent</a> (does not touch the problem)</li>
  <li><a href="https://stackoverflow.com/questions/7215615/how-to-insert-photo-in-call-intent">How to insert photo in call intent?</a> (is not related)</li>
  <li><a href="https://stackoverflow.com/questions/8574192/add-photo-to-an-android-contact">Add a photo to a contact</a> (does not use intent)
  
  <ul>
  <li><a href="https://stackoverflow.com/a/8574396/492624">https://stackoverflow.com/a/8574396/492624</a> (solution from answer I tried with intent, both PHOTO and DATA15 fields, but not working)</li>
  </ul></li>
  <li><a href="http://thinkandroid.wordpress.com/2009/12/30/handling-contact-photos-all-api-levels/" rel="nofollow noreferrer">http://thinkandroid.wordpress.com/2009/12/30/handling-contact-photos-all-api-levels/</a> (does not use intent)</li>
  </ul>
  
  <p>So is there anyone, who knows how to use Intent (as in example code) and insert a Photo, which is held in Bitmap ?</p>
  
  <p>Example code I do use now to start dialog intent for user to let him insert or cancel and possibly edit fields before saving:</p>
  
  <pre><code>// PrivateContactClass c;
  // Bitmap photo;
  Intent inOrUp = new Intent(ContactsContract.Intents.Insert.ACTION, ContactsContract.Contacts.CONTENT_URI);
  inOrUp.setType(ContactsContract.Contacts.CONTENT_TYPE);
  inOrUp.putExtra(ContactsContract.Intents.Insert.NAME, ModelUtils.formatName(c));
  inOrUp.putExtra(ContactsContract.Intents.Insert.PHONE, getPrimaryPhone());
  inOrUp.putExtra(ContactsContract.Intents.Insert.TERTIARY_PHONE, c.getMobile());
  inOrUp.putExtra(ContactsContract.Intents.Insert.EMAIL, c.getMail());
  inOrUp.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, c.getFunction());
  inOrUp.putExtra(ContactsContract.Intents.Insert.NOTES, getSummary());
  inOrUp.putExtra(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
  startActivity(inOrUp);
  </code></pre>
  
  <hr>
  
  <h1>I have found a solution, thanks to Julien's answer</h1>
  
  <p>Not using only intent, as I doubt that we can pass ID of image saved by Data ContentProvider, or pass Bitmap directly within Intent.  </p>
  
  <p>Extends from code above</p>
  
  <h2>Use startActivityForResult with constant request code</h2>
  
  <pre><code>// must be declared in class-context
  private static final int CONTACT_SAVE_INTENT_REQUEST = 1;
  ...
  startActivityForResult(inOrUp,CONTACT_SAVE_INTENT_REQUEST);
  </code></pre>
  
  <h2>Add handling result from activity started by Intent</h2>
  
  <pre><code>@Override
  protected void onActivityResult(int requestCode, int resultCode,
          Intent intent) {
      super.onActivityResult(requestCode, resultCode, intent);
      switch (requestCode) {
      case RESULT_INSERT_CONTACT:
          if (resultCode == RESULT_OK) {
              trySetPhoto();
          }
          break;
      }
  }
  </code></pre>
  
  <h2>Add Method to set photo</h2>
  
  <pre><code>public boolean setDisplayPhotoByRawContactId(long rawContactId, Bitmap bmp) {
       ByteArrayOutputStream stream = new ByteArrayOutputStream();
       bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
       byte[] byteArray = stream.toByteArray();
       Uri pictureUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, 
               rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
       try {
           AssetFileDescriptor afd = getContentResolver().openAssetFileDescriptor(pictureUri, "rw");
           OutputStream os = afd.createOutputStream();
           os.write(byteArray);
           os.close();
           afd.close();
           return true;
       } catch (IOException e) {
           e.printStackTrace();
       }
       return false;
   }
  </code></pre>
  
  <h2>Add Method to search for contacts and add contact photos</h2>
  
  <pre><code>private void trySetPhoto() {
      // Everything is covered in try-catch, as this method can fail on 
      // low-memory or few NPE
      try {
          // We must have an phone identifier by which we search for
          // format of phone number is not relevant, as ContentProvider will
          // normalize it automatically
          if (c.getMobile() != null) {
              Uri lookup = Uri.withAppendedPath(
                      ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                      Uri.encode(c.getMobile()));
              Cursor c = getContentResolver().query(lookup, null, null, null,
                      null);
              // Remember cursor can be null in some cases
              if (c != null) {
                  // we can obtain bitmap just once
                  Bitmap photo_bitmap = getPhotoBitmap();
                  c.moveToFirst();
                  // if there are multiple raw contacts, we want to set the photo for all of them
                  while (c.moveToNext()) {
                      setDisplayPhotoByRawContactId(
                              c.getLong(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID)),
                              photo_bitmap);
                  }
                  // remember to clean up after using cursor
                  c.close();
              }
          }
      } catch (Exception e) {
          // Logging procedures
      } catch (Error e) {
          // Logging procedures
      }
  }
  </code></pre>