Birthday Data Is Removed After Updating - android

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);

Related

How to delete all android contacts that start with a specific name?

I want to delete all contacts from my android phone that starts with a "AAA" or that contains "AAA" . Here's what I tried:
private void deleteContact(String name) {
ContentResolver cr = getContentResolver();
String where = ContactsContract.Data.DISPLAY_NAME + " = ? ";
String[] params = new String[] {"AAAA"};
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
.withSelection(where, params)
.build());
Log.e(",,,,",String.valueOf(ops.get(0)));
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();
}
Toast.makeText(NativeContentProvider.this, "Deleted the contact with name '" + name +"'", Toast.LENGTH_SHORT).show();
}
but failed. Please give me some idea so I can proceed further in my project.
Maybe this will get you on the right track:
ContentResolver mContentResolver = getContentResolver();
private int deleteContactsLike(String name) {
return mContentResolver.delete(
ContactsContract.RawContacts.CONTENT_URI,
ContactsContract.Contacts.DISPLAY_NAME
+ " like ?",
new String[] { name + '%'});

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();
}

Why Update contacts methods does nothing in android

I write an Update method to update contacts but after i run this on my phone nothing happen
and no contact get update why?
this is my method :
public Boolean UpdateContacts(ArrayList<ContactInfo> encryptedContactsInfoList) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ContentResolver cr = null;
for (ContactInfo contactInfo : encryptedContactsInfoList) {
try {
String contactId = contactInfo.getContactID();
String contactName = contactInfo.getContactName();
String contactNumber = contactInfo.getContactNumber();
ops.add(ContentProviderOperation
.newUpdate(Data.CONTENT_URI)
.withSelection(
ContactsContract.CommonDataKinds.Phone._ID
+ " = ?", new String[] { contactId })
.withValue(ContactsContract.Data.DISPLAY_NAME,
"asdffgh").build());
cr.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.d("exception", e.getMessage());
}
}
return true;
}
this is ops after executing the code:
[{"mSelection":"_id \u003d ?","mSelectionArgs":["2302"],"mUri":{"authority":
{"decoded":"com.android.contacts","encoded":"com.android.contacts"},"fragment":{},"path":
{"decoded":"NOT CACHED","encoded":"/data"},"query":{},"scheme":"content","uriString":"NOT
CACHED","host":"NOT CACHED","port":-2},"mValues":{"mValues":
{"display_name":"asdffgh"}},"mType":2,"mYieldAllowed":false}]
any help really appreciate,
best regards.
You get nothing because your ContentResolver is null, so you get an exception in every iteration.
Your app does not crash because you have catch (Exception e) that catches every exception.
try with:
ContentResolver cr = getContentResolver();
also, the applyBatch call should be after the for loop, otherwise you are procesing many times every item, and change ContactsContract.CommonDataKinds.Phone._ID to ContactsContract.Data._ID
try {
for (ContactInfo contactInfo : encryptedContactsInfoList) {
String contactId = contactInfo.getContactID();
String contactName = contactInfo.getContactName();
String contactNumber = contactInfo.getContactNumber();
ops.add(ContentProviderOperation
.newUpdate(Data.CONTENT_URI)
.withSelection(
ContactsContract.Data._ID
+ " = ?", new String[] { contactId })
.withValue(ContactsContract.Data.DISPLAY_NAME,
"asdffgh").build());
}
cr.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
Log.d("exception", e.getMessage());
}

Update contact with multiple phone numbers

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)

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