如何仅检索每个对话的最后一条消息,包括使用 Telephony.Sms 锁定的消息?

How to retrieve only the last message of every conversation including the locked message using Telephony.Sms?

我正在使用以下代码从短信中检索消息。

private List<String> getEveryLastMessages(){
    List<String> listSms = new ArrayList<String>();
    ContentResolver contentResolver = getActivity().getContentResolver();

    Cursor c = contentResolver.query(Telephony.Sms.Inbox.CONTENT_URI, // Official CONTENT_URI from docs
                new String[] { Telephony.Sms.Inbox.BODY }, // Select body text
                null,
                null,
                Telephony.Sms.Inbox.DEFAULT_SORT_ORDER); // Default sort order

    int totalSMS = c.getCount();

    if (c.moveToFirst()) {
        for (int i = 0; i < totalSMS; i++) {
            listSms.add(c.getString(0));
            listSms.add("\n");
            c.moveToNext();
        }
    } else {
        //Do something, no messages
    }
    c.close(); 

        return listSms;
}

我的问题是除了锁定的消息外,所有消息都已检索。

我想要实现的是仅检索的最后一条消息 每个对话,包括锁定消息,并将其填充到我的 recyclerview 适配器中,以将其显示为收件箱。

如果您想要每次对话中的最后一条消息,无论是发送还是接收,都可以使用方便的内置 URI,而不是只抓取所有内容并自行过滤。

Telephony.Sms.Conversations.CONTENT_URI(在 android.provider 包中)可用于 ContentResolver 查询以检索可用对话的摘要。例如:

Cursor c = contentResolver.query(Telephony.Sms.Conversations.CONTENT_URI,
                                 null, null, null, null);

此查询将 return 包含三列:

  • Telephony.Sms.Conversations.SNIPPET ("snippet")
  • Telephony.Sms.Conversations.MSG_COUNT ("msg_count")
  • Telephony.Sms.Conversations.THREAD_ID ("thread_id")

SNIPPET 列将是该对话中最新的可用消息。

不幸的是,从 Marshmallow(API 级别 21)开始,任何不是默认消息传递应用程序的应用程序都只能访问受限的 SMS table 视图。这样的应用程序只能接收 Telephony.Sms.TYPEMESSAGE_TYPE_INBOXMESSAGE_TYPE_SENT 的消息。这意味着您不会获得 MESSAGE_TYPE_FAILEDMESSAGE_TYPE_DRAFT 等,除非您的应用是当前默认应用。

但是,Telephony.Sms.LOCKED 列是与 TYPE 列完全不同的分类,因此不应包含在受限视图中。也就是说,无论您的应用程序是否为默认应用程序,只要它们是 sentinbox,您就应该能够获得锁定的消息或不。当然,制造商有可能改变了上述任何行为,您可能需要在您的应用中考虑到这一点。