Android:无法更新或删除与ContentProviderOperation的联系人

时间:2015-03-25 23:14:01

标签: android android-contentprovider contacts android-contacts

我正在尝试使用ContentProviderOperation在Android中创建插入/更新/删除联系人的简单操作。我已成功插入新的联系人,但之后我无法更新或删除它。

插入联系人后,我会以这种方式检索其ID:

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).withValue(...).build());
ContentProviderResult[] results = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
int idContact = Integer.parseInt(results[0].uri.getLastPathSegment());

并且id类似于557,然后我尝试使用:

更新(或删除)
String selection = Data.CONTACT_ID + "=?";
String[] selectionArgs = new String[] { String.valueOf(idContact) };

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI)
    .withValue(RawContacts.ACCOUNT_TYPE, null)
    .withValue(RawContacts.ACCOUNT_NAME, null).build());

if (firstName != null && surname != null) {
    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
        .withSelection(selection, selectionArgs)
        .withValueBackReference(Data.RAW_CONTACT_ID, 0)
        .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
        .withValue(StructuredName.GIVEN_NAME, firstName)
        .withValue(StructuredName.FAMILY_NAME, surname).build());
}

if (phoneNumber != null) {
    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
        .withSelection(selection, selectionArgs)
        .withValueBackReference(Data.RAW_CONTACT_ID, 0)
        .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
        .withValue(Phone.NUMBER, phoneNumber)
        .withValue(Phone.TYPE, Phone.TYPE_MOBILE).build());
}         

context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);   

没有给出错误,但联系人没有被修改,甚至删除都有效。 我做错了吗?

2 个答案:

答案 0 :(得分:2)

我终于设法解决了这个问题,错误不止一个。

1)

int idContact = Integer.parseInt(results[0].uri.getLastPathSegment());

返回RAW ID(即表的自动增量id)而不是CONTACT_ID,对于在该联系人上进行其他查询很有用。 因此,在插入联系人之后,我必须以其他方式检索新的contact_id,例如我已经根据显示名称进行了查询,但我认为您也可以使用电话号码。

ContentProviderResult[] results = context.getContentResolver()
                .applyBatch(ContactsContract.AUTHORITY, ops);
int raw_id = Integer.parseInt(results[0].uri.getLastPathSegment());
Log.d(TAG, "Raw id: " + raw_id);   // not so useful
// search for the contact_id
int contact_id;
String displayName = firstName + " " + surName;
String selection = ContactsContract.Contacts.DISPLAY_NAME + "=?";
String[] selectionArgs = new String[] { displayName };
Cursor cur = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection, selectionArgs, null);
if (cur != null) {      
    if(cur.moveToFirst())
        contact_id = cur.getInt(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
    cur.close();    
}
Log.d(TAG, "Insert complete for id: " + contact_id);

2) 在我的更新功能中有很多错误。 首先,正如Kai所说,第一个newUpdate语句(单独的一个)是没用的。 其次,在以下更新中,withValue调用是错误的。 第三,最重要的是,我必须添加一些选择,实际上简单的contact_id选择必须完成每种类型的特定选择(名称,电话,ecc ......)

这是正确的方法:

String baseSelection = Data.CONTACT_ID + "=?";
String[] baseSelectionArgs = new String[] { String.valueOf(idContact) };

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

if (firstName != null && surname != null) {
    String selection = baseSelection + " AND " + Data.MIMETYPE + "=?";
    String[] selectionArgs = new String[] { baseSelectionArgs[0],
        StructuredName.CONTENT_ITEM_TYPE };
    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
        .withSelection(selection, selectionArgs)
        .withValue(StructuredName.GIVEN_NAME, firstName)
        .withValue(StructuredName.FAMILY_NAME, surname).build());
}

if (phoneNumber != null) {
    String selection = baseSelection + " AND " + Data.MIMETYPE
        + "=? AND " + String.valueOf(Phone.TYPE) + " = ? ";
    String[] selectionArgs = new String[] { baseSelectionArgs[0],
        Phone.CONTENT_ITEM_TYPE, String.valueOf(Phone.TYPE_MOBILE) };
    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
        .withSelection(selection, selectionArgs)
        .withValue(Phone.NUMBER, phoneNumber).build());
}

答案 1 :(得分:0)

第二次和第三次更新看起来正确,但第一次更新

ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI)
    .withValue(RawContacts.ACCOUNT_TYPE, null) 
    .withValue(RawContacts.ACCOUNT_NAME, null).build()); 

看起来像插入而不是更新,删除此代码并重试。