Cambiar la imagen de contacto programáticamente

Tengo una foto, que está almacenada en el teléfono Android. Quiero poder cambiar la imagen de un contacto.

Lo que he hecho hasta ahora es iniciar el selector de contactos, hacer que el usuario seleccione un contacto y luego obtengo el URI del contacto seleccionado. De este contacto, puedo obtener el rawContact asociado y usoeste código.

Uri rawContactPhotoUri = Uri.withAppendedPath(
             ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
             RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
     try {
         AssetFileDescriptor fd =
             getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
         OutputStream os = fd.createOutputStream();
         os.write(photo);
         os.close();
         fd.close();
     } catch (IOException e) {
         // Handle error cases.
     }

El problema es que el AssetFIleDescriptor siempre está vacío (cuando llamo a length, siempre obtenemos -1).

No estoy pidiendo la solución completa, solo algunas pistas a seguir que me pueden ayudar a que funcione. Parece que no puedo encontrar este problema en StackOverflow, por lo que cualquier ayuda sería apreciada.

EDITAR

Siempre es cuando pedimos una pregunta que encontramos la solución. Quiero compartirlo por otro

Así que me di por vencido en el enlace de Android y encontré otro:http://wptrafficanalyzer.in/blog/programatically-adding-contacts-with-photo-using-contacts-provider-in-android-example/

El selector de imágenes devuelve el Uri del contacto seleccionado, por lo que con esto puede obtener el Contact._ID del mismo:

// This is onActivityResult
final Uri uri = data.getData();
final Cursor cursor1 = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
final long contactId = cursor1.getLong(cursor1.getColumnIndex(Contacts._ID);
cursor1.close();

Luego tuve que obtener el RawContactId:

final Cursor cursor2 = getContentResolver().query(RawContacts.CONTENT_URI, null,     RawContacts.Contact_ID + "=?", new String[] {String.valueOf(contactId)}, null);
cursor2.moveToFirst();
final long rawContactId = cursor2.getLong(cursor2.getColumnIndex(RawContacts._ID));
cursor2.close();

Luego tuve que obtener el Data._ID de RawContacts (de la misma manera que arriba).

Luego usé el ContentProviderOperations:

final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
    .withSelection(Data._ID, dataId),
    .withValue(Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
    .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, byteArrayOfThePicture);

getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

Y esto está funcionando a la perfección. Espero eso ayude

Respuestas a la pregunta(1)

Su respuesta a la pregunta