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?