Contact picture not adding to the Contact in my application - android

i want to add the image to the contacts, but i cant add the image to the contact, but if the contact image is existing it will replace the existing image and set. but while we are going for new one it is not working ...kindly help any one ...Thanks in advance
try {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 75, stream);
android.content.ContentProviderOperation.Builder builder = ContentProviderOperation
.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(
ContactsContract.Data.CONTACT_ID + "=?" + " AND "
+ ContactsContract.Data.MIMETYPE + "=?",
new String[] {
String.valueOf(contactId),
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE });
builder.withValue(
ContactsContract.CommonDataKinds.Photo.PHOTO,
stream.toByteArray());
ops.add(builder.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY,
ops);
} catch (Exception e) {
e.printStackTrace();
}
case R.id.assign_contact:
cropstatus = 2;
filepath = Environment.getExternalStorageDirectory().getPath()
+ "/Noredoo/Profile Pictures/" + file.getName();
startCropImage(filepath, 1, 1);
Intent contactintent = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(
Intent.createChooser(contactintent, "Choose Contact"),
PICK_CONTACT);
return true;

The problem you have is that when inserting a new image you need to use a different method as described here.
http://developer.android.com/reference/android/content/ContentProviderOperation.html#newInsert(android.net.Uri)
When the contact doesn't already have an image it's impossible to update the field because it doesn't exists. You should perform an insert operation instead.
Here is is a sample of a working code for achieving that goal:
// Creating new photo entry
int rawContactId = -1;
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {id}, null);
if(cursor.moveToFirst()) {
rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
if(rawContactId > -1) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photoBytes)
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
e.printStackTrace();
}

Related

Android - Update contacts without using Intent

Please help me, I am trying to update a contact by CONTACT_ID or by NAME. The only way i got it to work is with using Intent, but I want it to be updated in the background thread.
These are the code snippets I tried:
try {
String newName = "test";
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.CommonDataKinds.Phone._ID + "=? AND " +
ContactsContract.Contacts.Data.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'",
new String[]{"Alexa Prg"})
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, newName)
.build());
ContentProviderResult[] result = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
// Do Any thing
}
and
Activity context = new Activity();
try {
ContentResolver contentResolver = context.getContentResolver();
ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<>();
ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.CommonDataKinds.Phone._ID + "=? AND " +
ContactsContract.Contacts.Data.MIMETYPE + "='" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'",
new String[]{"560"}) //ID
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, newName)
.build());
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
}
Both the snippets aren't working

Function to update a photo in ContactsContract

I try to update a photo in ContactsContract with a function who take the id of the contact and the uri of the picture but it seem it's not working (and my function return true).
I really don't understand because the code look good.
It seem it's working when the contact have already a photo...
This is my function :
boolean updatePhoto(String idStr, String uri){
if (uri != null) {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
File imgFile = new File(uri.replace("file://", ""));
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + " = ?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{idStr, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, stream.toByteArray())
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
}
return true;
}
Your code only works if the contact already has a photo because your using ContentProviderOperation.newUpdate, if the contact doesn't have a photo you'll need to use ContentProviderOperation.newInsert.
You need to first query the contact to see if it has a photo, and then update/insert the new photo:
private boolean hasPhoto(long contactId) {
Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
InputStream input = Contacts.openContactPhotoInputStream(getContentResolver(), uri);
if (input == null) {
return false;
}
Bitmap photo = BitmapFactory.decodeStream(input);
return (photo != null);
}
private long getRawId(long contactId) {
String selection = RawContacts.CONTACT_ID + "='" + contactId + "'";
Cursor cur = contentResolver.query(RawContacts.CONTENT_URI, new String[]{ RawContacts._ID }, selection, null, null);
try {
if (cur.moveToNext()) {
return cur.getLong(0);
}
} finally {
cur.close();
}
return 0;
}
private boolean updatePhoto(long contactId, String uri) {
if (uri == null) {
// do nothing?
return false;
}
ContentProviderOperation.Builder builder;
if (hasPhoto(contactId)) {
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(Data.CONTACT_ID + " = ?" + " AND " + Data.MIMETYPE + "=?",
new String[]{ String.valueOf(contactId), Photo.CONTENT_ITEM_TYPE});
} else {
long rawId = getRawId(contactId);
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, rawId);
}
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Data.IS_SUPER_PRIMARY, 1);
builder.withValue(Data.IS_PRIMARY, 1);
byte[] photo = getPhotoAsByteArray(uri); // to simplify the answer's code
builder.withValue(Photo.PHOTO, photo);
try {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ops.add(builder.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch(Exception e) {
e.printStackTrace();
return false;
}
return true;
}

Android : Update exicting Contact List

I am trying to edit my contact list through my App. I can able to update Contact name , Phone number and Email. But, when I try to change existing photo it is not updating.
When I try to add new contact with image it is successfully added
Problem occur when I try to edit existing Contact with Image
Code that I using for Update Contact
ContentResolver contentResolver = getContentResolver();
String where = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] emailParams = new String[]{idValue, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE};
String[] nameParams = new String[]{idValue, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE};
String[] numberParams = new String[]{idValue, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE};
int photoRow = -1;
String wherePhoto = ContactsContract.Data.RAW_CONTACT_ID + " = " + idValue + " AND " + ContactsContract.Data.MIMETYPE + " =='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, wherePhoto, null, null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoRow = cursor.getInt(idIdx);
}
ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<android.content.ContentProviderOperation>();
ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
.withSelection(where,emailParams)
.withValue(ContactsContract.CommonDataKinds.Email.DATA, edt_contactEmail.getText().toString().trim())
.build());
ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
.withSelection(where,nameParams)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, edt_contact_name.getText().toString().trim())
.build());
ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
.withSelection(where,numberParams)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, edt_contactNumber.getText().toString().trim())
.build());
ByteArrayOutputStream stream = new ByteArrayOutputStream();
if(contact_bitmap!=null){ // If an image is selected successfully
contact_bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
byte[] b = stream.toByteArray();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data._ID + " = ?", new String[]{Integer.toString(photoRow)})
.withValue(ContactsContract.Data.RAW_CONTACT_ID, idValue)
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.DATA15, b)
.build());
try {
stream.flush();
}catch (IOException e) {
e.printStackTrace();
}
}
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
Toast.makeText(EditContacts.this,"Contact Successfully updated",Toast.LENGTH_LONG).show();
Intent i = new Intent(EditContacts.this,MainActivity.class);
finish();
startActivity(i);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
}
Can any one please tell me how to edit existing contact with image.
Thanks in advance :)
I have used this example for updating contact.
ContactManager
Method to update Contact:
boolean updateContact(String contactID, String contactName, String contactNumber, String contactEmailAdd, Bitmap bitmap) {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ops.add(ContentProviderOperation
.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE
+ "=?", new String[]{contactID, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contactName)
.build());
ops.add(ContentProviderOperation
.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE
+ "=? AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?"
, new String[]{contactID, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
, String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)})
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contactNumber)
.build());
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE
+ "=? AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?"
, new String[]{contactID, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
, String.valueOf(Email.TYPE_WORK)})
.withValue(Email.ADDRESS, contactEmailAdd)
.build());
try {
ByteArrayOutputStream image = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, image);
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " +
ContactsContract.Data.MIMETYPE + "=?", new String[]{contactID, Photo.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
.withValue(Photo.PHOTO, image.toByteArray())
.build());
/*Builder builder;
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{contactID, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
ops.add(builder.build());*/
} catch (Exception e) {
e.printStackTrace();
}
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

How to set default image to Android phone contact that has no previous image

I have a piece of code which updates the an Android contact´s image, the problem is that it doesn't work when the contact has no previous image. I also checked that the contact was from "Phone" account or "*#gmail.com" account. When it already has an image with these accounts I have no problem updating the image, the problem is just when the contact has no previous image assigned.
Here is the method in charge of updating the image.
public void update(long id, Bitmap bitmap) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// Picture
try
{
ByteArrayOutputStream image = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG , 100, image);
Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE});
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, image.toByteArray());
ops.add(builder.build());
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
this.context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e)
{
e.printStackTrace();
}
}
And here is how I know if the contact belongs to one of the two accounts I mentioned above:
// Getting the raw contact id
public static int getRawContactId(Context context, long id) {
String[] projection = new String[] { ContactsContract.RawContacts._ID };
String selection = ContactsContract.RawContacts.CONTACT_ID + "=?";
String[] selectionArgs = new String[] { String.valueOf(id) };
Cursor c = context.getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI, projection,
selection, selectionArgs, null);
int rawContactId = -1;
if (c.moveToFirst()) {
rawContactId = c.getInt(c
.getColumnIndex(ContactsContract.RawContacts._ID));
}
return rawContactId;
}
Here I get the account name for further analysis
//...
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
String[] rawProjection = { RawContacts._ID, RawContacts.ACCOUNT_NAME };
Cursor raw = context.getContentResolver().query(rawContactUri, rawProjection, null, null, null);
if (raw.moveToFirst()) {
account = raw.getString(1);
}
Thanks in advance.
The problem seems to be that, as you describe, you're updating the image
http://developer.android.com/reference/android/content/ContentProviderOperation.html#newUpdate(android.net.Uri)
instead of inserting a new one
http://developer.android.com/reference/android/content/ContentProviderOperation.html#newInsert(android.net.Uri)
If the contact doesn't has a previous image, it's impossible to update the field in the database because it doesn't exists. You should perform an insert operation instead.
It's debatable if the api method should fail hard throwing an exception at runtime.
Hope it helps.
After some research as suggested I found an approach that works just fine.
https://stackoverflow.com/a/15145256/2423274
Here is the relevant part:
// Create new photo entry
int rawContactId = -1;
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {id}, null);
if(cursor.moveToFirst()) {
rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
if(rawContactId > -1) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photoBytes)
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
e.printStackTrace();
}

Update contact image in android contact provider

I create an Application to Read, Update, Delete Contacts Details.
Here is a problem to updating Contact_Image.
When new contact Added by device outside the Application without image.
then we can't update contact Image.
My Updating Code is.
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(Data.CONTACT_ID+"= ? AND "+ContactsContract.Data.MIMETYPE+"=?",new String[]{id,ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE})
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, imageInByte)
.build());
Please provide Solution Regard this.
You will have different code for updating a photo then adding a photo to a contact that doesn't have one. From your description above I believe you are trying to insert an image and not update an image, but here is code for both:
if(hasPhoto(resolver, id) == true)
{
int photoRow = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " = " + id + " AND " + ContactsContract.Data.MIMETYPE + " =='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, where, null, null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoRow = cursor.getInt(idIdx);
}
cursor.close();
// Update current photo
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data._ID + " = ?", new String[] {Integer.toString(photoRow)})
.withValue(ContactsContract.Data.RAW_CONTACT_ID, id)
.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.DATA15, photoBytes)
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
// Create new photo entry
int rawContactId = -1;
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {id}, null);
if(cursor.moveToFirst())
{
rawContactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
if(rawContactId > -1)
{
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photoBytes)
.build());
try
{
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The difference being that if you are updating an existing photo you use the newUpdate function, but if you are inserting a photo to a contact that never had one you use newInsert

Categories

Resources