1

I'm using the below code to retrieve a message from 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;
}

my problem is all of the message was retrieved and except the locked message.

what I'm trying to achieve is retrieve only the last message of every conversation including the lock messages and populate it into my recyclerview adapater to show it as inbox.

Polar
  • 3,327
  • 4
  • 42
  • 77
  • Hmm, that doesn't seem like standard behavior. Are you certain the locked message is a received message? That is, are you sure it's in the inbox? Which Android version are you testing on? If this is an actual device, what is it, specifically? Also, you state that you want "the last message of every conversation". What if the last message is a sent message? Depending on your needs, [this post](https://stackoverflow.com/q/42068940) might be of some help. – Mike M. Oct 17 '17 at 00:54
  • Yup, The locked messages is a received messages. Not sure if the locked message is on inbox, but the default messenger of android has it in the list, it's just locked. I'm currently testing it on Android Marshmallow, and yes I'm using an actual device which model is INFINIX HOT S X521. It doesn't matter if the last message is sent, failed to send, draft, lock etc. as long as it is the last content in every conversation. Thanks, I'll check that post. – Polar Oct 17 '17 at 04:03
  • OK, I was just asking about received/inbox, 'cause that's all you're querying in your snippet there - `Telephony.Sms.Inbox.CONTENT_URI`. Anyhoo, starting with Marshmallow, non-default apps only have access to a restricted view of the SMS table, and can only get _inbox_ and _sent_ messages, so you won't get _failed_ or _draft_ messages unless your app is the default messaging app. However, _locked_ is a separate thing from those, and shouldn't figure into that restricted view, at least in the standard API. An OEM may change any of this, though. – Mike M. Oct 17 '17 at 04:21
  • awt. it's that so, let me try what I get from the link you shared. – Polar Oct 17 '17 at 04:23
  • 1
    @Mike M. - Please put you're comment into answer, I want to mark it as correct answer. Thank you! – Polar Oct 18 '17 at 03:20

1 Answers1

3

If you want the last message in each conversation, regardless of whether it's sent or received, there's a handy built-in URI that you can use, in lieu of just grabbing everything and filtering it yourself.

Telephony.Sms.Conversations.CONTENT_URI (in the android.provider package) can be used in a ContentResolver query to retrieve a summary of the available conversations. For example:

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

This query will return with three columns:

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

The SNIPPET column will be the most recent available message in that conversation.

Unfortunately, starting with Marshmallow (API level 21), any app that is not the default messaging app has access to only a restricted view of the SMS table. Such an app can only get messages with a Telephony.Sms.TYPE of MESSAGE_TYPE_INBOX or MESSAGE_TYPE_SENT. This means that you won't get MESSAGE_TYPE_FAILED, MESSAGE_TYPE_DRAFT, etc., unless your app is the current default app.

However, the Telephony.Sms.LOCKED column is a completely separate categorization from the TYPE column, and so should not figure into the restricted view. That is, you should be able to get locked messages, as long as they're sent or inbox, no matter if your app is the default or not. Of course, it's possible that a manufacturer has altered any of this described behavior, and you might need to account for that in your app.

Mike M.
  • 38,532
  • 8
  • 99
  • 95