Bogus
Bogus

Reputation: 245

Using ContentProviderOperation to update and insert contacts

I faced the problem updating/insertng contacts on Android 2.0+. There is no problem to insert a new contact when phone book is empty but when I did it 2nd time some fileds like TEL, EMAIL are doubled and tripped etc. but N, FN, ORG are ok (one copy).

After getting and advice of other member this forum I updated a contact first and then ContentProviderResult[] returned uri's with null then I do an insert action and it went ok but after that I made an update and all contacts are aggregated into one - i got 1 contact insted 3 which existed in phone book. This one was damaged, the contact fields are randomly built.

I set Google account.

Code:

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  ops.add(ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI)
    .withValue(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED)
    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType)
    .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
    .build()); 

// add name
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
   builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
   builder.withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME, name);

// phones
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
   builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
   builder.withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
   builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneValue);
   builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
   builder.withValue(ContactsContract.CommonDataKinds.Phone.LABEL, phoneLabel);         
   ops.add(builder.build());

// emails ...
// orgs ...

try {

  ContentProviderResult[]  result = mContentResolver.applyBatch(ContactsContract.AUTHORITY, ops);   
 }
  } catch (Exception e) {
   Log.e(LOG_TAG, "Exception while contact updating: " + e.getMessage());
  }

What is wrong in this solution ? How does work aggregation engine ?

I will be glad for help.

Bogus

Upvotes: 10

Views: 14470

Answers (3)

David-mu
David-mu

Reputation: 1772

You must provide a where clause for each ContentProviderOperation if you want to do an update, See here and here.

Upvotes: 2

Maurycy
Maurycy

Reputation: 3961

you are redefining the builder without adding it to ops therefore the data is never being sent for names which explains why your aggregation is so wierd.

// add name
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);

// phones
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);

also due to readability i prefer to use the following format when dealing with smaller batches....

ArrayList<ContentProviderOperation> batchOp = new ArrayList<ContentProviderOperation>();
batchOp.add(ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI) 
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType).build());

Upvotes: 0

wiseideal
wiseideal

Reputation: 65

I met the same problem.I think it should work in this way

opt.add(ContentProviderOperation.newUpdate(ContactsContract.Contacts.CONTENT_URI)
                .withSelection(ContactsContract.Contacts._ID, new String[]{entity.getPeople()})
                .withValue(ContactsContract.Contacts.DISPLAY_NAME, "daerba")
                .build()
        );

But it went wrong and report this.

android.database.sqlite.SQLiteException: bind or column index out of range

I think there must be a selection to update a contact.So the withSelection is important to tell the ContentResolver which contact to update.

Hoping this can give some clue.

Upvotes: 1

Related Questions