-1

I am using the Telephony.Sms library to load in received and sent sms messages for the app I am working on. When I set the query selection to null (the third item in the query), it will show all the sent and received sms messages on the different types of phones I have been testing on.

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

But when I set it to a particular number, on the Samsung S9 phone running on API 27 it is not showing any sms messages. On the Nexus runnning on API 23, it will show the received messages but not the sent messages in the listview. On the Huawei phone running on API 22, it's all working properly, showing the sent and received messages of the particular number.

Cursor c = cr.query(Telephony.Sms.CONTENT_URI, null, sms, null, null);

Here's the full code retrieving the sent and received sms messages for a particular phone number.

@WithPermissions(permissions = {Manifest.permission.READ_SMS})
    public void getAllSms(Context context)
    {
        // Number needs to saved in +614 format
        String phoneNumber = SelectedPhNo;
        String sms = "address='"+ phoneNumber + "'";

        ContentResolver cr = context.getContentResolver();
        Cursor c = cr.query(Telephony.Sms.CONTENT_URI, null , null , null , null);  // Sms not showing up on Raza's phone
        int totalSms = 0;


        String type = null;
        if(c != null)
        {
            totalSms = c.getCount();

            if(c.moveToFirst())
            {
                for(int j = 0; j < totalSms; j++)
                {
                    String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));
                    String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));
                    switch(Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE))))
                    {
                        case Telephony.Sms.MESSAGE_TYPE_INBOX:
                            type = "inbox";
                            break;
                        case Telephony.Sms.MESSAGE_TYPE_SENT:
                            type = "sent";
                            break;
                        case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
                            type = "outbox";
                            break;
                        default:
                            break;
                    }

                    // Convert smsDate to readable format
                    Long date = Long.parseLong(smsDate);

                    // Convert millis value to proper format
                    Date dateVal = new Date(date);

                    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
                    dateText = format.format(dateVal);

                    //Toast.makeText(context, "Message present", Toast.LENGTH_SHORT).show();
                    inboxArrayAdapter.add("Command: " + body + "\n" + "Date: "+ dateText);

                    // Iterate through the list of SMS messages to be displayed in the listview
                    c.moveToNext();

                    //  Update listview as soon as we receive a new message
                    ((BaseAdapter)inboxmessages.getAdapter()).notifyDataSetChanged();

                    inboxArrayAdapter.notifyDataSetChanged();;
                }
            }
        }
        else
        {
            Toast.makeText(getContext(), "No Messages found for this contact!", Toast.LENGTH_SHORT).show();
        }
    }
Sahil Bora
  • 173
  • 1
  • 12

2 Answers2

1

Querying for SMS/MMS messages is very tricky, and varies a lot between different Android versions and between different makers.

This is the version that should work properly on all Android K+ devices:

HashSet<String> phonesSet = new HashSet<>();
phonesSet.add(phoneNumber);
long threadId = Threads.getOrCreateThreadId(context, phonesSet); // get the thread-id of the specific conversation thread
Uri threadUri = ContentUris.withAppendedId(Threads.CONTENT_URI, threadId); // get the thread-uri

String[] projection = new String[]{MmsSms.TYPE_DISCRIMINATOR_COLUMN, BaseColumns._ID, Conversations.THREAD_ID,
                    Telephony.Sms.ADDRESS, Telephony.Sms.BODY, "sort_index", Telephony.Sms.DATE_SENT,
                    Telephony.Sms.READ, Telephony.Sms.TYPE, Telephony.Sms.STATUS, Telephony.Sms.LOCKED,
                    Telephony.Sms.ERROR_CODE, Telephony.Sms.SEEN};

Cursor cur = getContentResolver().query(threadUri, projection, null, null, null);
DatabaseUtils.dumpCursor(cur);
marmor
  • 27,641
  • 11
  • 107
  • 150
  • Hey man thanks for your solution. I'm trying to implement it but for the cursor line, can we put the sent/received messages in a listview instead of a database. – Sahil Bora Apr 23 '19 at 00:02
  • of course, the `DatabaseUtils.dumpCursor` line was just to show you in the log that it contains all the data you need, now you can loop through that cursor, read the data you want out of each row, and put everything in a ListView. – marmor Apr 23 '19 at 06:50
  • I tried looping through the cursor with code provided but nothing was showing in the listview – Sahil Bora Apr 23 '19 at 07:45
  • you need to populate the listview yourself, it doesn't come automatically with cursors, read it into some memory collection like an arraylist, and have the listview show that arraylist – marmor Apr 23 '19 at 08:53
  • Can you redo your answer with populating the listview, ive tried 3 times now it's only showing the android cursor raw stuff in my attempts – Sahil Bora Apr 23 '19 at 09:23
  • you need to map specific `columns` from the cursor onto specific `textviews` in your listview's row layout, see here: https://developer.android.com/reference/android/widget/SimpleCursorAdapter – marmor Apr 23 '19 at 13:11
-1

This is the full code solution of being able to obtain the Sent/Received SMS messages on various android devices. This has been tested on API level 22, 23, 26 and 28 on different android devices including Huawei, Oppo and Samsung.

public void getAllSms(Context context)
{
    HashSet<String> phoneSet = new HashSet<>();
    phoneSet.add(SelectedPhNo);  // phoneNumber
    long threadId = Telephony.Threads.getOrCreateThreadId(context, phoneSet);
    Uri threadUri = ContentUris.withAppendedId(Telephony.Threads.CONTENT_URI, threadId);

    String[] projection = new String[] {Telephony.MmsSms.TYPE_DISCRIMINATOR_COLUMN, BaseColumns._ID, Telephony.Sms.Conversations.THREAD_ID,
            Telephony.Sms.ADDRESS, Telephony.Sms.BODY, "sort_index", Telephony.Sms.DATE_SENT, Telephony.Sms.DATE,
            Telephony.Sms.READ, Telephony.Sms.TYPE, Telephony.Sms.STATUS, Telephony.Sms.LOCKED,
            Telephony.Sms.ERROR_CODE, Telephony.Sms.SEEN, Telephony.Sms.Inbox.BODY, Telephony.Sms.Sent.BODY};

    Cursor cur = context.getContentResolver().query(threadUri, projection, null, null, "normalized_date desc"); 
    DatabaseUtils.dumpCursor(cur);

    // Read cursor into an arraylist
    ArrayList<String> mArrayList = new ArrayList<String>();

    int totalSms = cur.getCount();

    if(cur.moveToFirst())
    {
         for(int i = 0; i < totalSms; i++)
         {
              String body = cur.getString(cur.getColumnIndex(Telephony.Sms.BODY));
              String indexDate = cur.getString(cur.getColumnIndex(Telephony.Sms.DATE));

              // Convert string to long variable
              Long date = Long.parseLong(indexDate);

              // Convert millis value to proper format
              Date dateVal = new Date(date);

              //"dd-MMM-yyyy""dd/MM/yyyy"
              SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss  dd-MM-yyyy");
              dateText = format.format(dateVal);

              cur.moveToNext();

              inboxArrayAdapter.add("Command: " + body + "\n" + "Date: " + dateText);
         }
    }
}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Sahil Bora
  • 173
  • 1
  • 12