在Android 2.x中删除(原始)联系人

时间:2011-09-08 16:32:19

标签: android unit-testing android-emulator contacts

我正在为我的Android应用程序进行单元测试,并且正在使用“联系人”做很多事情。我必须将联系人插入Android内容提供商,并在运行我的测试后删除它们。麻烦的是,它们实际上没有被删除:

插入:

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

int backRefIndex = 0;

Random r = new Random();

    contactOps.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                                           .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                                           .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) 
                                           .build());      
    contactOps.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                                           .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRefIndex)
                                           .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                                           .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "Sample Name" + r.nextInt())
                                           .build());

    contactOps.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                       .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backRefIndex)
                       .withValue(ContactsContract.CommonDataKinds.Phone.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                       .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "020" + r.nextInt())
                       .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, r.nextInt(20)
                       .build());

    try {
        ContentProviderResult[] result = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, contactOps);
    } catch (Exception e) {
        e.printStackTrace();
    }

删除方法1(返回原始联系人的数量,但实际上并未删除):

int deletedRawContacts = context.getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts._ID + " >= ?", new String[]{"0"});

删除方法2(与删除方法1相同,但方法不同):

private static int deleteAllRawContacts(Context context) {
    ContentResolver cr = context.getContentResolver();
    Cursor cur = cr.query(ContactsContract.RawContacts.CONTENT_URI, null, null, null, null);
    int count = 0;
    while (cur.moveToNext()) {
        try {
            String contactId = cur.getString(cur.getColumnIndex(ContactsContract.RawContacts._ID));
                count += cr.delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.RawContacts._ID + " = ?", new String[]{contactId});
        } catch (Exception e) {
            System.out.println(e.getStackTrace());
        }
    }
    return count;
}

“联系人”的删除方法有效,但“原始联系人”的删除方法将返回false值。它将“告诉”我删除了所有联系人,但是当我运行下一个测试用例时,仍然可以找到旧的原始联系人(即插入的联系人与当前联系人的计数错误)。注意:所有测试都在Android模拟器上完成。

任何想法如何解决这个问题?

我在这里看到了一个类似的问题:How to delete a contact? - 但解决方案似乎也无法解决给定的问题。

2 个答案:

答案 0 :(得分:20)

正如smartideal已经提到的那样,删除rawcontacts的方式只会将“deleted”-flag设置为1。

您需要做的是将URI中的caller_is_syncadapter-flag设置为true,如下所示:

RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build()

然后使用这个新的URI来调用delete-method:

int deletedRawContacts = context.getContentResolver().delete(RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build(), ContactsContract.RawContacts._ID + " >= ?", new String[]{"0"});

文档中的相应部分为here(操作 - >删除)。

希望这有助于编码:#)。

答案 1 :(得分:0)

我正在处理同样的问题。我发现删除列设置为1一旦我“删除”它。所以我认为contentresolver不会在物理上删除rawcontact数据,它只是设置了一个删除标志。也许我们应该避免这些标签