2

I am creating an SMS manager for KitKat and later version. I have implemented all the receivers as directed in the official doc by android.

I have to receive the SMS SMS_DELIVER broadcast receiver and read it and then have to write to the SMS provider.

till now I am able to read the SMS received. I have set my app as the default SMS app in the device. I am also parsing the SMS and can see it in the log.

problem

I am unable to write the SMS to the SMS provider.

here is the broadcast receiver:

public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    if (bundle != null) {

        Object[] pdusObj = (Object[]) bundle.get("pdus");

        SmsMessage[] messages = new SmsMessage[pdusObj.length];

        for (int i = 0; i < messages.length; i++) {
            String format = bundle.getString("format");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i], format);
            } else {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
            }
        }
        for (SmsMessage msg : messages) {
            Log.i("log", "display msg body  : " + msg.getDisplayMessageBody() + "originating address : " + msg.getDisplayOriginatingAddress() + " get message body : " + msg.getMessageBody());

            //here I have to write the message to the sms provider.
        }

    }
  }
}

does anyone have any suggestions? please help me.

Update

i have tried android-kitkat-api-19-how-to-write-messages-in-sms-content-provider-without so question but i am unable to get around it. That solution is for writing to the sent SMS without doing anything like sending the SMS. but I want to write the received SMS here.

Sagar Nayak
  • 2,138
  • 2
  • 19
  • 52
  • [http://stackoverflow.com/a/27709655/4049612](http://stackoverflow.com/a/27709655/4049612) May be it will help you – Krishna May 19 '16 at 10:24
  • Possible duplicate of [Android KitKat (API 19) - How to write messages in SMS Content Provider, without sending them, from Non-Default App?](http://stackoverflow.com/questions/27697282/android-kitkat-api-19-how-to-write-messages-in-sms-content-provider-without) – Ahmad Aghazadeh May 19 '16 at 10:26
  • @ahmadaghazadeh please see my update . – Sagar Nayak May 19 '16 at 10:32
  • Yeah, my answer on [that post](http://stackoverflow.com/questions/27697282) only works in KitKat. They patched the hole for the versions after that. Starting with Lollipop, your app absolutely _must_ be the default SMS to have write access to the Provider. [The post](http://stackoverflow.com/a/30133663) you pinged me on earlier is the minimum that you have to have in your app for it to show up in the list of apps eligible to be default. You also have to actually set it as default before you can write to the Provider. That said, if you're testing on KitKat, my `SmsWriteOpUtil` class should work – Mike M. May 19 '16 at 10:42
  • @MikeM. i have done everything. i have set it to default sms app and all those things. i need to write now to the sms provider. and my target api is lollipop and M . please suggest – Sagar Nayak May 19 '16 at 10:46
  • Oh, you just write it like you would to any `ContentProvider`. There's a really simplified example in [my post here](http://stackoverflow.com/questions/28853979/sms-doesnt-save-on-kitkat-4-4-already-set-as-default-messaging-app/28854600#28854600). – Mike M. May 19 '16 at 10:49
  • ohhk . but is there any official doc that says what are the value i have to put into the content provider. as this will be saved in database and after i uninstall my app other messaging app will read that message. so there must be some kind of standard form for that . right ? @MikeM. – Sagar Nayak May 19 '16 at 11:02
  • There's no official docs for that, AFAIK. You can dig through [the source](https://android.googlesource.com/platform/packages/apps/Mms/+/master/src/com/android/mms) to see what it writes, but I can't recall exactly where that's at, atm. The address, body, and date are pretty much sufficient, I believe. The _type_ defaults to inbox, and _read_ defaults to 0, IIRC. – Mike M. May 19 '16 at 11:13

2 Answers2

4

Thanks to Mike M. for the help. i got help from this answer - sms-doesnt-save-on-kitkat-4-4-already-set-as-default-messaging-app from SO and this post - kitkat-sms-mms-supports .

here is what i have done :

to write the sms into the sms provider of android system i used content provider. and passed value to it. code snippet is :

ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, msg.getDisplayOriginatingAddress());
values.put(Telephony.Sms.BODY, msg.getMessageBody());
context.getApplicationContext().getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);

this code will save the received sms into the system sms provider and even after your ap is uninstalled other sms app can read it. keep in mind that you need to be the default sms app to do this operation. and you have to provide WRITE_SMS permission in manifest. i have targeted kitkat and versions after it. for previous versions you have to some part of code differently.

the whole SmsReceiver class after completion is :

public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    if (bundle != null) {

        Object[] pdusObj = (Object[]) bundle.get("pdus");

        SmsMessage[] messages = new SmsMessage[pdusObj.length];

        for (int i = 0; i < messages.length; i++) {
            String format = bundle.getString("format");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i], format);
            } else {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
            }
        }
        for (SmsMessage msg : messages) {
            Log.i("log", "display msg body  : " + msg.getDisplayMessageBody() + "originating address : " + msg.getDisplayOriginatingAddress() + " get message body : " + msg.getMessageBody());
            ContentValues values = new ContentValues();
            values.put(Telephony.Sms.ADDRESS, msg.getDisplayOriginatingAddress());
            values.put(Telephony.Sms.BODY, msg.getMessageBody());
            context.getApplicationContext().getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
        }

    }
  }
}
Community
  • 1
  • 1
Sagar Nayak
  • 2,138
  • 2
  • 19
  • 52
  • 2
    Keep in mind that if you're going to send messages from your app, you need to write those, as well, in which case you'd definitely want to include the appropriate [message type](https://developer.android.com/reference/android/provider/Telephony.TextBasedSmsColumns.html) in the `ContentValues`. – Mike M. May 19 '16 at 11:50
  • It doesn't work on Lollipop. Message was not written in the default android SMS database if you don't set it as default.. – mboy Oct 25 '16 at 07:15
  • yes . there is only one default sms app. and it has to manually write all the sms it receives to the database. and if it wants not to write those sms then there will be no sms in database. – Sagar Nayak Oct 25 '16 at 08:03
0

I had the same problem. You have to register a SMSBroadcaseReceiver, MMSBroadcastReceiver, a QuickreplyService in order to be be able to be set as default SMS receiver.

This helped me: https://www.androidauthority.com/how-to-create-an-sms-app-part-2-724264/

honky-tonk
  • 73
  • 1
  • 6