Angel Koh
Angel Koh

Reputation: 13485

Bulk update of more than 500 contacts

I am developing an app that needs to update many contacts and I am getting the following error.

android.content.OperationApplicationException: Too many content provider operations between yield points. The maximum number of operations per yield point is 500

I tried breaking the contacts up into smaller chunks to update, but I still get the same error. The good thing is that now, some contacts are updated (previously 0 contacts are updated). Any suggestions that can help me is greatly appreciated.

    Uri uri = ContactsContract.Data.CONTENT_URI;
    String selectionUpdate = ContactsContract.CommonDataKinds.Phone._ID + " = ? AND " + ContactsContract.Contacts.Data.MIMETYPE + " = ? ";

    int i = 0;
    int numRowsUpdated = 0;
    int batchsize = 100;
    for (EntityPhone ep : eps) { 
        if (ep.isUpdateNumber()) {

            //update only when checkbox is ticked
            ops.add(ContentProviderOperation.newUpdate(uri)
                    .withSelection(selectionUpdate, new String[]{ep.getPhoneId(), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE})
                    .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, ep.getPhoneNumberNew())
                    .build());

            i++;
            if (i % batchsize == 0) {

                i = 0;
                ContentProviderResult[] count = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);

                if (count != null) {
                    numRowsUpdated += count.length;
                    Log.i(TAG, "batch update success" + count.length);
                } else {

                    Log.w(TAG, "batch update failed");
                }
            }
        }
    }

    if (i != 0) {
        ContentProviderResult[] count = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
    }

I have looked at the past questions, but they are mostly related to inserts, not updates.

The reason why I want to update so many records at once is because my application is a 'contact number formatter' that allows the user to standardizes all the phone numbers in the phone easily. I do not have control of how many records the users want to update in a single batch. (https://play.google.com/store/apps/details?id=angel.phoneformat)

Upvotes: 7

Views: 3828

Answers (1)

Andy McSherry
Andy McSherry

Reputation: 4725

You're not creating a new object for ops. During subsequent calls to applyBatch, you're passing the previously applied operations back in as well. The first time ops contains 100 elements, then 200 and eventually it fails when it reaches 500. Change to

if (i % batchsize == 0) {
    contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
    ops = new ArrayList<ContentProviderOperation>(100);
}

Upvotes: 8

Related Questions