We have run into a weird problem on our Nexus devices which recently updated to Lollipop.
Contacts that are added through the program can no longer be deleted. It either gives no option to delete or, if it does, then the delete itself doesn't work (even though it says that it does). Funnily enough, I downloaded a 3rd party contacts application and it has no problem deleting them.
Similarly, we can't delete it through the program. These are all things that worked perfectly before the upgrade.
This is the code that is used to insert the contact:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
.build());
if(contact.phone != null && contact.phone !=" "){
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.phone)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,Phone.TYPE_WORK)
.build());
}
if(contact.phone2 != null && contact.phone2 !=" "){
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.phone2)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,Phone.TYPE_WORK)
.build());
}
if(contact.phone3 != null && contact.phone3 !=" "){
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.phone3)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,Phone.TYPE_WORK)
.build());
}
if(contact.fax != null && contact.fax !=" "){
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.fax)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,Phone.TYPE_FAX_WORK)
.build());
}
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET,(" ".equals(contact.getAddress())?contact.location:contact.getAddress()))
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Organization.COMPANY,ctx.getResources().getString(R.string.meuhedet))
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, Long.parseLong(Groupid))
.build());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap photo = BitmapFactory.decodeResource(ctx.getResources(),R.drawable.logo_meuhedet);
photo.compress(Bitmap.CompressFormat.PNG, 100, baos);
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, baos.toByteArray())
.build());
try {
ContentProviderResult [] res =ctx.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
rawContactID = ContentUris.parseId(res[0].uri);
Log.d(TAG,"contact added = " + rawContactID);
boolean result = db.saveContactsIntoDatabase(rawContactID, index, ContactKey);
if(res[0].uri!=null && result){
((Activity) ctx).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(ctx, R.string.successfully_saved_contact, Toast.LENGTH_SHORT).show();
}
});
}
} catch (Exception e) {
}
}
As can be see, we save the id returned so that we can then use it in the delete:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
.withSelection(ContactsContract.RawContacts.CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)})
.build());
try {
ContentProviderResult [] res = ctx.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Log.d(TAG,"delete count= " + res[0].count);
if(res[0].count > 0 && result){
((Activity) ctx).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(ctx, R.string.successfully_deleted_contact, Toast.LENGTH_SHORT).show();
}
});
}
} catch (Exception e) {
}
The delete returns 0 for the number of rows affected so it is obviously not deleting it.
Is this a problem with Lollipop or is something wrong in the way we are adding the contact?
After days of "fighting" with the application I found out the cause.
It appears that you now have to supply a type (StructuredPostal.TYPE) for an address. Without it, it simply doesn't work properly.
This only seems to be the case with Lollipop. We tested it on other versions and no problem.
I would have expected the insert to fail if type is now compulsory.