Удалить SMS с помощью contentResolver слишком медленно

Я хотел бы удалить все SMS на моем телефоне, кроме 500 последних SMS для каждого разговора. Это мой код, но он очень медленный (удаление одного SMS занимает около 10 секунд). Как я могу ускорить этот код:

    ContentResolver cr = getContentResolver();
    Uri uriConv = Uri.parse("content://sms/conversations");
    Uri uriSms = Uri.parse("content://sms/");
    Cursor cConv = cr.query(uriConv, 
            new String[]{"thread_id"}, null, null, null);

    while(cConv.moveToNext()) {
        Cursor cSms = cr.query(uriSms, 
                null,
                "thread_id = " + cConv.getInt(cConv.getColumnIndex("thread_id")),
                null, "date ASC");
        int count = cSms.getCount();
        for(int i = 0; i < count - 500; ++i) {
            if (cSms.moveToNext()) {
                cr.delete(
                        Uri.parse("content://sms/" + cSms.getInt(0)), 
                        null, null);
            }
        }
        cSms.close();
    }
    cConv.close();

person Guillaume    schedule 14.01.2014    source источник
comment
сколько у тебя разговоров? и сколько всего смс за разговор у тебя было, когда ты удалял?   -  person kAnNaN    schedule 14.01.2014
comment
У меня около 34000 смс и около 100 разговоров. Но в одном разговоре 26000 смс   -  person Guillaume    schedule 14.01.2014
comment
я думаю, это довольно приличное время, учитывая, что вы выполняете условную операцию двойного курсора в базе данных. Это также зависит от мобильного телефона, который вы используете.   -  person kAnNaN    schedule 14.01.2014
comment
У меня Xperia S, и я пытаюсь в другой версии закрыть два курсора перед удалением, но это все равно очень медленно   -  person Guillaume    schedule 14.01.2014


Ответы (1)


Одна из основных вещей, которую вы можете сделать, это пакетные операции ContentProvider вместо 33 900 отдельных удалений:

// Before your loop
ArrayList<ContentProviderOperation> operations = 
    new ArrayList<ContentProviderOperation>();

// Instead of cr.delete use
operations.add(new ContentProviderOperation.newDelete(
    Uri.parse("content://sms/" + cSms.getInt(0))));

// After your loop
try {
    cr.applyBatch("sms", operations); // May also try "mms-sms" in place of "sms"
} catch(OperationApplicationException e) {
    // Handle the error
} catch(RemoteException e) {
    // Handle the error
}

Вы можете выбрать, хотите ли вы выполнить одну пакетную операцию для каждого разговора или одну пакетную операцию для всей истории SMS.

person ianhanniballake    schedule 14.01.2014