开发者

Using ContentProviderOperation to update and insert contacts

开发者 https://www.devze.com 2023-01-02 03:50 出处:网络
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

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


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


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消