Удаление (Raw) контактов в Android 2.x - PullRequest
7 голосов
/ 08 сентября 2011

Я работаю над модульными тестами для своего приложения для 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;
}

Метод удаления для контактов работает, но метод удаления для необработанных контактоввернет ложное значение.Он «скажет» мне, что он удалил все контакты, но когда я запускаю свой следующий тестовый пример, старые «сырые» контакты все еще могут быть найдены (т. Е. Неправильное число вставленных контактов против существующих контактов).Примечание. Все тесты выполняются на эмуляторе Android.

Есть идеи, как решить эту проблему?

Я видел подобный вопрос здесь: Как удалить контакт? -но решение, похоже, тоже не решает данную проблему.

Ответы [ 2 ]

20 голосов
/ 01 января 2012

Как уже упоминалось в wiseideal, при удалении rawcontacts только флаг "удален" будет установлен на 1.

Что вам нужно сделать, это установить флаг caller_is_syncadapter в вашем URI на true, как это:

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

А затем используйте этот новый URI для вызова метода delete:

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

Соответствующая часть в документации здесь (Операции-> Удалить).

Надеюсь, это поможет и удачного кодирования:)

0 голосов
/ 10 октября 2011

Я работаю над той же проблемой. Я обнаружил, что для столбца удаления установлено значение 1, как только я его "удаляю". Поэтому я думаю, что contentresolver физически не удаляет необработанные данные, он просто устанавливает флаг удаления. Возможно, нам следует избегать этих тег.

...