将Android Sms Conversation标记为已读。 Sql查询一次又一次地执行。(错误)

时间:2016-07-18 19:23:50

标签: java android database sqlite android-contentprovider

我正在尝试将Android聊天线程中的所有邮件标记为已读。我正在使用我从AOSP项目复制的以下代码,但我的应用程序进入ANR并且我不断收到日志中的消息。

ContentValues sReadContentValues = new ContentValues(2);
sReadContentValues.put("read", 1);
sReadContentValues.put("seen", 1);
private static final String UNREAD_SELECTION = "(read=0 OR seen=0)";
context.getContentResolver().update(threadUri, sReadContentValues, UNREAD_SELECTION, null);

在循环中重复记录消息

SQLiteConnectionPool:   executeForChangedRowCount started 152577ms ago - running, sql="UPDATE sms SET read=?,seen=? WHERE (read=0 OR seen=0) AND thread_id=1464"

我一直在努力解决这个问题,但我们仍然没有运气。

1 个答案:

答案 0 :(得分:1)

这是一个旧线程,但我发现它正在寻找如何正确使用ContentValue类型并且它回答了我的问题,所以我会回答它...

循环日志消息: 您只发布了一小部分代码,因此我最好的猜测是,每次选择消息时都会执行此更新 - 在代码循环中。如果 这种情况,由于您试图在一次执行中更新整个线程,将这部分代码移动到自己的方法(假设它尚未存在)并调用是合乎逻辑的。它只有一次,在你收到所有想要的信息并且你已退出循环之后。

应用程序输入ANR 虽然您发布的日志消息显示为“(读取= 0或看到= 0)AND thread_id = 1464”,但您的代码仅在您的Where子句中反映“(读取= 0或看到= 0)” - 这显然会导致一些挫败感由于您将尝试更新每个消息线程中的每条消息。

虽然尝试更新所有现有线程的方法对于处理器而言会非常耗时,但如果您也在循环中执行此操作(正如您的日志消息所暗示的那样),那么它会产生很多感觉你会收到一个ANR,即使你要求它只运行一个thread_id ......

<强>解决方案: 随意纠正我,但做出一些逻辑假设,我相信这是你的解决方案:

public void mainMethod()
{
    String threadId = "1464";
    Cursor cursor = getSomeMessages(threadId);
    if (cursor != null && cursor.moveToFirst()) {
        do {
            // ... Do something with the message
        } while (cursor.moveToNext());
        cursor.close();
    }

    updateMessagesToReadAndSeen(threadId);
}

private void updateMessagesToReadAndSeen(String threadId) {
    if (threadId != null && !threadId.isEmpty()) {
        ContentValues sReadContentValues = new ContentValues(2);
        sReadContentValues.put("read", 1);
        sReadContentValues.put("seen", 1);
        String UNREAD_SELECTION = "(read=0 OR seen=0) AND thread_id=" + threadId;
        context.getContentResolver().update(threadUri, sReadContentValues, UNREAD_SELECTION, null);
    }
}

我想如果我必须就“范围友好的变化”提出一些建议,那就是将它分解为更灵活的方法。例如...

private void UpdateContent(Uri uri, ContentValues values, String _where, String[] args) {
    _context.getContentResolver().update(uri, values, _where, args);
}

...

private static String UNREAD_UNSEEN_THREADID = "(read=0 OR seen=0) AND thread_id=";

private void updateMessagesReadAndSeen(String threadId, int setRead, int setSeen) {
    if (threadId != null && !threadId.isEmpty()) {
        ContentValues sReadContentValues = new ContentValues(2);
        sReadContentValues.put("read", setRead);
        sReadContentValues.put("seen", setSeen);

        UNREAD_UNSEEN_THREADID +=  threadId;
        UpdateContent(threadUri, sReadContentValues, UNREAD_UNSEEN_THREADID, null);
    }
}

我可以永远继续下去,但是当您为产品开发新功能时,这将允许更多的灵活性。祝你好运!