I'm trying to set contact photo by using the function in the official android docs here,but the function changes the photo off completely different contact although i check the contactURI
and contactID
and use it to get the contact name and still changes the wrong contact photo.
Test example:
picked contact id: 4673
the value off rawContactPhotoUri in writeDisplayImage(): content://com.android.contacts/raw_contacts/4673/display_photo
the id for of the contact whom photo was changed by error: 147
My Process
I select the image and then select the contact using startActivityForResult(), then execute the function
My Code
onActivityResult() is:
else if (requestCode == SELECT_CONTACT_FOR_RESULT) {
if (resultCode == RESULT_OK) {
contactUri=data.getData();
setContactImage(contactUri, selectedImageURI, MainActivity.this)
} else {
//}
}
the setContactImage()
public static void setContactImage(final Uri rawContactUri, final Uri selectedImageURI, final Activity activity, final boolean isFromShare) {
final String nameString = getContactName(rawContactUri, activity);//get name using URI
final long contactID = ContentUris.parseId(rawContactUri);
if (writeDisplayPhoto(activity, contactID, getByteFromIMGUri(activity, selectedImageURI))) {//success toast }
writeDisplayImage()
private static boolean writeDisplayPhoto(Activity activity, long contactID, byte[] photo) {
Uri rawContactPhotoUri = Uri.withAppendedPath(
ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactID),
ContactsContract.RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
Debug.d(activity, "contactID: " + contactID + "rawContactPhotoUri: " + rawContactPhotoUri);
try {
AssetFileDescriptor fd =
activity.getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
OutputStream os = fd.createOutputStream();
os.write(photo);
os.close();
fd.close();
return true;
} catch (IOException e) {
Debug.e(activity, "Write Photo EXCEPTION: " + e);
return false;
// Handle error cases.
}
}
getContactName()
static String getContactName(Uri rawContactUri, Context context) {
Cursor cursor; // Cursor object
cursor = context.getContentResolver().query(rawContactUri, null, null, null, null);
cursor.moveToFirst();
int phoneIndex = cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME);
String string = cursor.getString(phoneIndex);
cursor.close();
Debug.d(context, "Name: " + string + " ,ID: " + ContentUris.parseId(rawContactUri) + " ,URI: " + rawContactUri, false);
return string;
}
You seem to have a confusion between Contact ID
and RawContact ID
.
In ContactsContract a Contact is comprised of multiple RawContacts. The ID of a Contact is not the same as the IDs of its RawContacts, and it's possible that the same ID will be used for some Contact but also some totally different RawContact (as you noticed with the wrong contact getting updated).
The is in line:
setContactImage(contactUri, selectedImageURI, MainActivity.this)
where you're passing a ContactUri (with a Contact ID) to a method that expects a RawContactUri (with a RawContact ID).
You also have some errors when getting the ID out of a RawContactUri and calling it contactId wrongly.
Here's some code to find some random RawContactUri
from a given ContactUri
:
Uri getSomeRawContactUri(Uri contactUri) {
long contactId = ContentUris.parseId(contactUri);
String[] projection = new String[] { RawContacts._ID };
String selection = RawContacts.CONTACT_ID + " = " + contactId;
Cursor cursor = context.getContentResolver().query(RawContacts.CONTENT_URI, projection, selection, null, null);
if (cursor != null && cursor.moveToFirst()) {
long rawContactId = cursor.getLong(0);
cursor.close();
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
return rawContactUri;
}
return null;
}