-1

I want to do the following:

  • Send an SMS
  • Check if it was sent
  • Store it in a SQLite instance if it wasn't.
  • Resend any SMS that got stored before.

So you got a main SMS sending action, which will require feedback on its status (to tell the user if it could be sent or not), and a background SMS sending action which will just try to resend previously unsent SMS silently.

The solution I came up with involves an IntentService which has two actions:

  • Send an SMS message.
  • Try to send previously stored SMS messages.

So far so good, this exact same thing worked wonders for sending a TCP message to a server. Now the issue is that I can't seem to be able to send SMS from the IntentService.

The idea was to have the IntentService create a PendingIntent, stuff the main Activity provided PendingIntent inside (thats basically the callback to tell the activity the SMS was sent), then send the SMS with it.

Then with a static receiver fetch the PendingIntent and start a new action on the IntentService to delete the SMS from the SQLite instance if it was sent properly.

This is the main message sending method in the IntentService:

private void sendMessage(Configuration cfg, SMSMessage msg, PendingIntent resultIntent) {
    final Intent smsIntent;
    // Select which kind of intent we're creating.
    if (resultIntent == null) {
        // This one is the silent background SMS.
        smsIntent = new Intent(this.getApplicationContext(), RedirectPendingMessages.class);
    } else {
        // This one is the one from the application.
        smsIntent = new Intent(this.getApplicationContext(), RedirectMessage.class);
        smsIntent.putExtra(EXTRA_PENDING_RESULT, resultIntent);
    }
    // Now store the message.
    smsIntent.putExtra(EXTRA_SMS, msg);
    // Construct broadcast intent.
    PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 0, smsIntent, 0);
    // Now send message.
    SmsManager smsMng = SmsManager.getDefault();
    smsMng.sendTextMessage(cfg.phoneNumberFor(msg.level), null, msg.content, pi, null);
}

It gets to the 'SmsManager.sendTextMessage' method fine but nothing happens, even if I hardcode the phone number and dont pass any PendingIntent the SMS still doesn't gets sent. It might be because the IntentService ceases to exist after the method call?

The receivers both just grab the broadcasted Intent, fetch the data inside, and start appropiate actions in the IntentService to delete the SMSs if they have been sent, and to broadcast the application's PendingIntent so the UI can give some feedback to the user ("SMS sent", "Error", etc).

My TCP implementation of the same thing pretty much just has a Socket write instead of that 'sendTextMessage', it blocks the IntentService until its done and works fine.

Any ideas on why the SMS isn't being sent or how to better implement this?

TheStack
  • 553
  • 4
  • 12
  • 1
    How long are your messages? If they're over the limit for the character set you're using, `sendTextMessage()` will just fail silently. If that's the case, split up the messages and use the `sendMultipartTextMessage()` method instead. – Mike M. Sep 15 '15 at 13:32
  • Dang, good idea! I'll check it right now. – TheStack Sep 15 '15 at 13:38
  • HOLY MACARONI DUDE! Two parts! Length is around 120, divideMessage returns two parts! Gotta try it from the IntentService now... – TheStack Sep 15 '15 at 13:52
  • Yup, now I can send SMS, it seems it was just what you described, sendTextMessage failing silently because the message was too long (although I thought I had up to 140 characters, oh well...). If you want to post that as an answer I'll accept it gladly :) – TheStack Sep 15 '15 at 15:07
  • 1
    Ah, good. Glad it worked. I'll write up an answer little later, when I get a moment. Cheers! – Mike M. Sep 15 '15 at 16:55

1 Answers1

1

It seems that your message exceeds the character limit for the alphabet you're using, which is causing the SmsManager#sendTextMessage() method to fail silently.

For the basic 7-bit default alphabet, the character limit is 160; for 8-bit, it's 140; and for 16-bit, which sounds like your situation, it's 70, explaining why your 120-character message split into two parts.

As you discovered, you can use the SmsManager#divideMessage() method to split a message into useable parts, and the SmsManager#sendMultipartTextMessage() to send the parts correctly.

SmsManager Reference

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