2

I'm new to android development. I want to send some SMS Message from my background service that it will fetch some data from the server and send it to some clients. So far it was working perfectly till they added some description to text messages. Since then, some of my messages are not sent.

Here is what I have done till now :

for (MessageData messageData : result) {
    String message = messageData.getBody();
    String recipient = messageData.getRecipient();

    int parts_size = smsManager.divideMessage(message).size();
    if (parts_size > 1) {
        ArrayList<String> parts = smsManager.divideMessage(message);
                smsManager.sendMultipartTextMessage(recipient, null, parts, null, null);
    } else {
        smsManager.sendTextMessage(recipient, null, message, null, null);
    }
}

I don't know if android can handle sending messages in for-loop or if I am doing something wrong.

Thank you for helping.

chornge
  • 2,021
  • 3
  • 28
  • 37
Pouya Samie
  • 3,718
  • 1
  • 21
  • 34
  • add a breakpoint in the `else` block and run in debugger mode. then see if it is reached and check that the size of the message (with description) is less than 160 (the maximum size of an sms message). – chornge Oct 04 '17 at 19:03
  • yes it reaches there if the message is less than 160 and I checked the DB the max number characters is 491 – Pouya Samie Oct 04 '17 at 19:06
  • it reaches the `else` conditional? if that's the case, it means your `parts_size` is not greater than 1. – chornge Oct 04 '17 at 19:07
  • no it reaches the else condition just when text messages are less than 160 – Pouya Samie Oct 04 '17 at 19:08
  • oh i see. if the max number of characters in DB is 491, then it means your `parts_size` should not be greater than 3 (160 * 3 is 480). – chornge Oct 04 '17 at 19:10
  • maybe u can try using `if (parts_size > 1 && parts_size < 4)`, so if the message is broken into 4 parts, the `else` conditional gets reached and u can handle showing the user a message that their text is too long. – chornge Oct 04 '17 at 19:12
  • so you mean if i have 4 part messages it should send via regular sending message? – Pouya Samie Oct 04 '17 at 19:14
  • but as this link said http://www.textanywhere.net/faq/is-there-a-maximum-sms-message-length it can send till 918 characters there should be no problem – Pouya Samie Oct 04 '17 at 19:15
  • i see. what is the DB storing? also, u never use `result` in ur for-each-loop. should you be using `result`.getBody() instead of `messageData`.getBody() ? – chornge Oct 04 '17 at 19:20
  • im using messageData result is a list of object that store body and number! – Pouya Samie Oct 04 '17 at 19:21
  • oh right, i had it backwards. what is ur DB storing? – chornge Oct 04 '17 at 19:21
  • it stores messages in a column nvarchar – Pouya Samie Oct 04 '17 at 19:22
  • 1
    Using an unthrottled loop to send SMS is not a great idea. You can usually get away with it for a small number of relatively short messages, but it can easily lead to a silent failure for multiple/long messages. You'll want to wait to send a message until the previous one has completed. Each `SmsManager#send*()` method takes `PendingIntent` arguments that you can use to fire an `Intent` when a send is complete. [This answer](https://stackoverflow.com/a/24845193) has a simple example of how to do that for single-part messages. For multipart, it would be similar, but you would provide an... – Mike M. Oct 04 '17 at 23:05
  • 2
    ...`ArrayList` of `PendingIntent`s instead, one for each part. When the previous message's final part's `Intent` fires, then you would send the next message. Also, you can just use `sendMultipartTextMessage()` for everything. It will handle the single-part messages as well. – Mike M. Oct 04 '17 at 23:05
  • thank you Mike M. can you give me code sample ? by the way i was looking for that i will be thankful if you add your comments as answer – Pouya Samie Oct 05 '17 at 12:03

1 Answers1

2

I tried to follow and use Mike M's very insightful guidance and code to write an SMS message sending service that enqueues (large or small) messages and waits for each message to be completely sent before sending the next one. Most of the real work is done in the background.

SmsService.java is a gist on GitHub because it's a bit large to paste here.

One of my goals was to see if I could put the necessary functionality into one single android component. It's been tested with small numbers of messages but it's still experimental. (e.g. it avoids using a BroadcastReceiver, relies on the uniqueness of Service startIds sent in by the system, heavily relies on intents to represent messages, etc.)

The class has three static methods for setting it up, sending messages, and tearing it down:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    SmsService.setup(this);
}

private void sendMyMessages() {
    SmsService.send(this, recipient, sender, "the message text");
}

@Override
protected void onDestroy() {     
    SmsService.teardown(this);
    ...
}
albert c braun
  • 2,650
  • 1
  • 22
  • 32