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
Related
I'm trying to use this code to allow a user edit a contact's name and number. I get no errors and when I print nameofcontact and numberofcontact in my log it shows me the latest changes I've made to the name and number of the contact.
But it's not saving to my contacts database. Any ideas what's wrong?
public void editButton(View view) {
// the text in the 'nameofcontact' edittext box, can be modified by the user
contactname = nameofcontact.getText().toString();
// the text in the 'numberofcontact' edittext box, can be modified by the user
contactnumber = numberofcontact.getText().toString();
ContentResolver cr = getContentResolver();
String where = ContactsContract.Data.DISPLAY_NAME + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ? AND " +
String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE) + " = ? ";
String[] params = new String[] {contactname,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)};
Cursor phoneCur = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, where, params, null);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// if ( (null == phoneCur) ) {
// createContact(name, phone);
// } else
{
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(where, params)
.withValue(ContactsContract.CommonDataKinds.Phone.DATA, contactnumber)
.build());
}
phoneCur.close();
try {
cr.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println (contactname);
System.out.println (contactnumber);
Toast.makeText(this, "Updated", Toast.LENGTH_SHORT).show();
}
Please check you add below permission in your manifeast or not
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
and you can use this method it works for me.
public boolean updateContact(String name, String number, String ContactId) {
boolean success = true;
String phnumexp = "^[0-9]*$";
try {
name = name.trim();
number = number.trim();
if (name.equals("") && number.equals("")) {
success = false;
} else if ((!number.equals("")) && (!match(number, phnumexp))) {
success = false;
} else {
ContentResolver contentResolver = SwipableHomeActivity.this
.getContentResolver();
String where = Data.CONTACT_ID + " = ? AND "
+ Data.MIMETYPE + " = ?";
String[] nameParams = new String[]{
ContactId,
StructuredName.CONTENT_ITEM_TYPE};
String[] numberParams = new String[]{
ContactId,
Phone.CONTENT_ITEM_TYPE};
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
if (!name.equals("")) {
ops.add(ContentProviderOperation
.newUpdate(
Data.CONTENT_URI)
.withSelection(where, nameParams)
.withValue(StructuredName.DISPLAY_NAME, name)
.build());
}
if (!number.equals("")) {
ops.add(ContentProviderOperation
.newUpdate(
Data.CONTENT_URI)
.withSelection(where, numberParams)
.withValue(Phone.NUMBER, number).build());
}
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
} catch (Exception e) {
e.printStackTrace();
success = false;
}
return success;
}
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();
}
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();
}
I have this code
public void updateContact (String contactId, String newNumber) {ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String selectPhone = Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "='" +
Phone.CONTENT_ITEM_TYPE + "'";
String[] phoneArgs = new String[]{contactId};
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(selectPhone, phoneArgs)
.withValue(Phone.NUMBER, newNumber)
.build());
try { getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
which i took from here How to update contact number using Android and changed it in order to pass through all my contacts and add to each one of them a prefix of my own.
I run through all contacts and i provide with this
String id = phones.getString(phones.getColumnIndex(ContactsContract.Contacts._ID));
the Contact's id to the function above. But some contacts Especially the ones that have multiple numbers and some that have only one number, do not change to get the new prefix even though the given id is correct?! .
Do i miss something here i don't know what to change. I think it may be the mime type but i can imagine that someone may not used the Android preinstalled types for phones and used a custom type.
I do not get any errors. Thanks everyone for your time!!!
I finally changed my code to work properly, i was passing the contact ID but i needed the phone id ...here is the correct code.
public void updateContact (String contactId, String newNumber) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String selectPhone = Data._ID + "=? AND " + Data.MIMETYPE + "='" +
Phone.CONTENT_ITEM_TYPE + "'";
String[] phoneArgs = new String[]{contactId};
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(selectPhone, phoneArgs)
.withValue(Phone.NUMBER, newNumber)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Do not forget to set the appropriate permissions on android manifest (write contacts)
I've been trying to add/update birthdays in my contact list. I am able to add birthdays however I have problems when updating the birthday.
Waiting for a couple of seconds after updating, the birthday data disappears/gets deleted.
I've noticed that just after updating the birthday, the "dirty" field gets set to "1", which I guess triggers a syncing mechanism (I am just starting with contacts)
Here are the snippets that I am using
INSERT/ADD BIRTHDAY
long rawContactId = -1;
String[] projection = new String[]{ContactsContract.CommonDataKinds.Event.RAW_CONTACT_ID};
String selection = ContactsContract.CommonDataKinds.Event.CONTACT_ID + "=?";
String[] selectionArgs = new String[]{
String.valueOf(bdayContact.getId())
};
Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
projection,
selection,
selectionArgs, null);
try {
if (c.moveToFirst()) {
rawContactId = c.getLong(0);
}
} finally {
c.close();
}
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Event.START_DATE, bday)
.withValue(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UPDATE BIRTHDAY
String selection = ContactsContract.CommonDataKinds.Event.CONTACT_ID+"=? AND " +
ContactsContract.CommonDataKinds.Event.MIMETYPE+"=? AND " +
ContactsContract.CommonDataKinds.Event.TYPE+"=?"
;
String[] selectionArgs = new String[]{
String.valueOf(contacts.get(position).getId()),
String.valueOf(ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE),
String.valueOf(ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY)
};
Cursor cursor = managedQuery(ContactsContract.Data.CONTENT_URI, null, selection, selectionArgs, null);
if(cursor.moveToFirst()){
int index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event._ID);
String eventId = cursor.getString(index);
String bday = year+"-"+(monthOfYear+1)+"-"+dayOfMonth;
}
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
.withSelection(ContactsContract.Data._ID + " = ?", new String[] {eventId})
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Event.START_DATE, bday)
.withValue(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I found the problem!
The data gets deleted due to incorrect formatting.
It seems that leading zeros in the month and day fields are important. One thing I noticed though, that when inserting new birthdays, it doesn't matter if you don't have leading zeros.
String bday = year+"-"+String.format("%02d", (monthOfYear+1))+"-"+String.format("%02d", dayOfMonth);