CodingIntrigue
CodingIntrigue

Reputation: 78585

Using new Telephony content provider to read SMS

According to the 4.4 SMS APIs, the new version provides functionality to:

allow apps to read and write SMS and MMS messages on the device

I can't find any information on this functionality, nor any samples in the new SDK. This is what I have so far for reading new incoming messages.

However, I would like to read existing messages stored on the deivce:

// Can I only listen for incoming SMS, or can I read existing stored SMS?
SmsMessage[] smsList = Telephony.Sms.Intents.getMessagesFromIntent(intent);
for(SmsMessage sms : smsList) {
    Log.d("Test", sms.getMessageBody())
}

Please note: I know about using the SMS Content Provider, however this method is unsupported. According to the linked APIs, I should be able to do this in a supported way.

Upvotes: 12

Views: 22060

Answers (3)

hichris123
hichris123

Reputation: 10233

It looks like you would be able to use this class to get it working. The package is Telephony.Sms.Conversations.

Although the following code uses the content provider method, this is now an official API added in API Level 19 (KitKat) for reading the SMS messages.

public List<String> getAllSmsFromProvider() {
  List<String> lstSms = new ArrayList<String>();
  ContentResolver cr = mActivity.getContentResolver();

  Cursor c = cr.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++) {
          lstSms.add(c.getString(0));
          c.moveToNext();
      }
  } else {
      throw new RuntimeException("You have no SMS in Inbox"); 
  }
  c.close();

  return lstSms;
}

Upvotes: 32

LONGI
LONGI

Reputation: 11453

I did it like the following. Create SMSObject:

public class SMSObject {
  private String _id;
  private String _address;
  private String _msg;
  private String _readState; // "0" for have not read sms and "1" for have
                            // read sms
  private String _time;
  private String _folderName;

  //+ getter and setter methods and 

  @Override
  public String toString() {
    return "SMSObject [_id=" + _id + ", _address=" + _address + ", _msg="
            + _msg + ", _readState=" + _readState + ", _time=" + _time
            + ", _folderName=" + _folderName + "]";
}

And here a simple function, which simply logs all current SMS-Objects

private void readSMS() {
    List<SMSObject> lstSms = new ArrayList<SMSObject>();
    SMSObject objSms = new SMSObject();
    Uri message = Uri.parse("content://sms/");
    ContentResolver cr = this.getContentResolver();

    Cursor c = cr.query(message, null, null, null, null);
    // this.startManagingCursor(c);
    int totalSMS = c.getCount();
    Log.d("SMS Count->", "" + totalSMS);
    if (c.moveToFirst()) {
        for (int i = 0; i < totalSMS; i++) {

            objSms = new SMSObject();
            objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
            objSms.setAddress(c.getString(c
                    .getColumnIndexOrThrow("address")));
            objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
            objSms.setReadState(c.getString(c.getColumnIndex("read")));
            objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
            if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) {
                objSms.setFolderName("inbox");
            } else {
                objSms.setFolderName("sent");
            }

            lstSms.add(objSms);

            Log.d("SMS at " + i, objSms.toString());

            c.moveToNext();
        }
    }
    // else {
    // throw new RuntimeException("You have no SMS");
    // }
    c.close();

    // return lstSms;

}

Upvotes: 1

Pontus Backlund
Pontus Backlund

Reputation: 1017

I found this some days ago, can't remember from what site; You can only restore messages if the user has chosen to make the app the default sms app. This may or may not answer your question fully. I haven't tried this yet

  1. Query the current default SMS app's package name and save it.

    String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(context);
    
  2. Request the user change the default SMS app to your app in order to restore SMS messages (you must be the default SMS app in order to write to the SMS Provider).

    Intent intent = new Intent(context, Sms.Intents.ACTION_CHANGE_DEFAULT);
    intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, context.getPackageName());
    startActivity(intent);
    

Upvotes: 0

Related Questions