42

OK. I am sending text messages through my app. After a text message is sent, it sends a status update to a server. This portion works okay, but the problem I am running into is twofold. I am not sure if they are related, but I assume that they are.

My app has the ability to send a single text to multiple users. Here is a sample of the code...

if(phoneNumbers.length > 0 && message.getText().toString().equals("") == false)
{
    for(int i=0;i<phoneNumbers.length;i++)
    {
        sms = SmsManager.getDefault();
        try
        {
            sms.sendTextMessage(phoneNumbers[i], null, message.getText().toString(), null, null);
            sentQuantity++;
        }
        catch(IllegalArgumentException e)
        {

        }
    }
}

Basically, it just loops through an array of phone numbers, and sends the text one at a time. Here is where part of my issue lies. If I choose 3 or more numbers to send the text to, sometimes not all of the texts actually get sent. It happens very randomly.

I assume it is because there is a delay between sending each individual message, but the code doesn't wait long enough. I reached this assumption because if I step into the program using eclipse and manually go through the app, everything always works just fine.

My other issue is when I send off the text message status update to a web server.

Immediately after the text messages get sent, the app then connects to the internet and tells the server via an http post the number of texts that were sent. Here is my snippet of internet code...

for(int i = 0; i < postNames.length; i++)
{
    nameValuePairs.add(new BasicNameValuePair(postNames[i], postValues[i]));
    }

    //http post
    try{

            HttpParams httpParameters = new BasicHttpParams();
            int timeoutConnection = 10000;

            HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection );

            HttpClient httpclient = new DefaultHttpClient(httpParameters);              
            HttpPost httppost = new HttpPost(webAddress);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();

This section just compiles the items for the post, connects to a web page, and sends the post. The key here is the 10 second connection timeout. Once again, like I said earlier, the internet connection happens immediately after sending the texts. So, if I go into debug mode and manually step through the process, everything works fine. But if I just run the app on my phone, I will get a connection time out error.

Now, I am hoping that if I can reduce the number of text messages to one single text, regardless of the number of recipients, that would be awesome. I have tried separating the phone numbers with a comma, and that didn't work. I also tried separating the numbers with a semi-colon (exactly like how Microsoft Outlook, or GMail lets you add multiple recipients to an email). None of those worked for me. Does anyone have any suggestions? Even if there is a different approach altogether, that would be appreciated. Oh, and I don't want to use the Google Messaging intent to send the messages, I need to use my own app.

Lucas Bailey
  • 707
  • 1
  • 7
  • 15
  • FYI, a comma in telephony is a pause, not a separator. For example, if you call a number and have to wait before typing an extension, you could write `2135551212,,,,123` This will call the number, wait 5 x pause, then further dial 123. – Alexis Wilke Aug 04 '17 at 07:42

4 Answers4

74

You actually need to send the next sms after the previous one is sent, for this you need to check the status of the sms sent, please see this tutorial, it says:

If you need to monitor the status of the SMS message sending process, you can actually use two PendingIntent objects together with two BroadcastReceiver objects, like this:

 //---sends an SMS message to another device---
    private void sendSMS(String phoneNumber, String message)
    {        
        String SENT = "SMS_SENT";
        String DELIVERED = "SMS_DELIVERED";

        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
            new Intent(SENT), 0);

        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
            new Intent(DELIVERED), 0);

        //---when the SMS has been sent---
        registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode())
                {
                    case Activity.RESULT_OK:
                        Toast.makeText(getBaseContext(), "SMS sent", 
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                        Toast.makeText(getBaseContext(), "Generic failure", 
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                        Toast.makeText(getBaseContext(), "No service", 
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                        Toast.makeText(getBaseContext(), "Null PDU", 
                                Toast.LENGTH_SHORT).show();
                        break;
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        Toast.makeText(getBaseContext(), "Radio off", 
                                Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        }, new IntentFilter(SENT));

        //---when the SMS has been delivered---
        registerReceiver(new BroadcastReceiver(){
            @Override
            public void onReceive(Context arg0, Intent arg1) {
                switch (getResultCode())
                {
                    case Activity.RESULT_OK:
                        Toast.makeText(getBaseContext(), "SMS delivered", 
                                Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        Toast.makeText(getBaseContext(), "SMS not delivered", 
                                Toast.LENGTH_SHORT).show();
                        break;                        
                }
            }
        }, new IntentFilter(DELIVERED));        

        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);        
    }
Sam
  • 7,252
  • 16
  • 46
  • 65
Yaqub Ahmad
  • 27,569
  • 23
  • 102
  • 149
  • 1
    That doesn't answer my question. The short version of the question was, "How can I combine my multiple text messages into a single text message with multiple recipients?" – Lucas Bailey Dec 20 '11 at 17:35
  • 1
    You actually need to send the next sms before the previous one is sent – Yaqub Ahmad Dec 20 '11 at 17:50
  • I don't follow...Are you saying that I need to monitor my texts, and wait until the first one is sent before I send the next one, and so on for however many text messages I am sending? – Lucas Bailey Dec 20 '11 at 17:56
  • Have you tried, by setting some delay in your code: Please see this: http://stackoverflow.com/questions/4199191/how-to-set-delay-in-android-onclick-function – Yaqub Ahmad Dec 20 '11 at 18:00
  • 5
    @YaqubAhmad thanks for the answer. Though, I've also found that it's necessary to call `unregisterReceiver(this);` in the `OnRecieve()` callbacks when we are done with the broadcast, otherwise we end up with leaked intent receivers. – JWL Jul 31 '13 at 20:02
  • @nemesisfixx Even after adding `unregisterReceiver(this);` in the `OnRecieve()`, am getting leak error in logcat. What could be the problem? – Braj Oct 07 '14 at 06:58
  • @Braj am unsure without looking at the code... maybe a code paste would do? – JWL Oct 07 '14 at 11:29
  • @nemesisfixx Actually I am leaving Activity after registering receiver (flow is like that). So, its getting leaked. No problem with sent receiver as its onReceive method gets called soon but problem with deleivered receiver. Anything to register receiver globally? – Braj Oct 08 '14 at 05:58
  • 1
    Why is this answer the accepted one? "You actually need to send the next sms before the previous one is sent" makes no sense, how are you going to send a second sms before the first one is sent... Are people just voting because it provides some useful code even though it doesn't answer the question? Or am I just missing something? If so, please excuse me... – Pin Oct 09 '14 at 23:55
  • @Pin. The sentence should be "send next sms after previous one ..." It has been fixed now. Thanks – Yaqub Ahmad Oct 10 '14 at 05:48
  • 1
    @LucasBailey If I understand the answer, it is implying that you can't actually send a single text message to multiple recipients. Is that correct? – Michael Jan 23 '15 at 02:39
  • how to get message text which is send by above code? – Rajat Jun 22 '17 at 08:52
  • I don't understand how this actually works. Will the destructors of the `sendPI` and `deliveredPI` block until their `onReceived()` function gets called once? Because you call `sendTextMessage()` the same way otherwise... and it does not look like it will be waiting on the message to be sent. – Alexis Wilke Aug 04 '17 at 07:50
19

I guess this is what u need. The below snippet provides to to enter long message and divide them into part and send each of it individual to a given contact or even for a group of contacts

public void sendLongSMS() {

    String phoneNumber = "0123456789";
    String message = "Hello World! Now we are going to demonstrate " + 
        "how to send a message with more than 160 characters from your Android application.";

    SmsManager smsManager = SmsManager.getDefault();
    ArrayList<String> parts = smsManager.divideMessage(message); 
    smsManager.sendMultipartTextMessage(phoneNumber, null, parts, null, null);
}
mamba4ever
  • 2,662
  • 4
  • 28
  • 46
2

First you must add permission in AndroidManifest.xml file

<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

then write this code

try {

                String ph="1234568790";
                String msg="Haiii friend";

                SmsManager smsManager = SmsManager.getDefault();
                smsManager.sendTextMessage(ph, null,msg, null, null);
                Toast.makeText(MainActivity.this, "Message Sent",
                        Toast.LENGTH_LONG).show();
            }
            catch (Exception e)
            {
                Toast.makeText(MainActivity.this, "Message not Sent",
                        Toast.LENGTH_LONG).show();
            }
Antony jackson
  • 247
  • 3
  • 5
  • 1
    This doesn't answer the question asked, which was how to send the message to multiple numbers, not just one as this code (which is essentially identical to the code in the original question) does. – Jules Sep 28 '16 at 12:53
-1

You can try this

SmsManager.getDefault().sendTextMessage(phoneNUmber, null, messageToSend, null, null);

Thanks

Abhishek Dhiman
  • 1,631
  • 6
  • 25
  • 38
  • This doesn't answer the question asked, which was how to send the message to multiple numbers, not just one as this code (which is essentially identical to the code in the original question) does. – Jules Sep 28 '16 at 12:53