Search code examples
javaandroidservicesmsmanager

How to send message to multiple numbers using Service?


I want to send message to multiple numbers. I tried to use SMS manager. But it's not working.

I am doing it onPostExecute method of an AsyncTask. But I want to create a service and send messages from that service because user can close the application before messages sending gets complete so it should be working in background.

I have created a arraylist of numbers. Now this I want to send to service and send message to each number.

My attempt:

@Override
public void doPostExecute(JSONArray response) throws JSONException {

    ArrayList<String> numbers = new ArrayList<>();

    for (int i = 0; i < response.length(); i++) {

        JSONObject subObject1 = response.getJSONObject(i);

        String status = subObject1.getString("status");

        if (status.equals("1")) {

            JSONObject invitation = subObject1.getJSONObject("invitation");

            String number = invitation.getString("invitee_no");

            numbers.add(number);
        } else {

        }
    }

    try {
        SmsManager sms = SmsManager.getDefault();
        PendingIntent sentPI;
        String SENT = "SMS_SENT";

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

        sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
        sms.sendTextMessage("8655864341", null, "Hi,add me to your unique contact list.",sentPI, null);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

I have added permission for send sms in manifest.

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

How can I do this? Can anyone help please? Thank you..

EDIT:

I tried to write service like below:

    public class MessageService extends Service {

    ArrayList<String>  numbers = new ArrayList<>();
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        numbers = intent.getStringArrayListExtra("numbers");

        for(int i=0;i<numbers.size();i++) {

            sendMsg(numbers.get(i));
        }

        return super.onStartCommand(intent, flags, startId);
    }

    public void sendMsg(final String num){
        String SENT = "SMS_SENT";
        final SmsManager sms = SmsManager.getDefault();
        final PendingIntent sentPI = PendingIntent.getBroadcast(MessageService.this, 0,new Intent(SENT), 0);
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                sms.sendTextMessage("8655864341", null, "Hi MyApp SMS", sentPI, null);
            }
        }, 2000);
    }

    @Override
    public IBinder onBind(Intent intent)
    {

    //    numbers = intent.getStringArrayListExtra("numbers");

        return null;
    }
}

And calling it from an activity:

       Intent serviceIntent = new Intent(this,MessageService.class);
    serviceIntent.putStringArrayListExtra("numbers",numbers);
    startService(serviceIntent);

Added service in manifest:

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

<service android:name=".helper.MessageService"></service>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".Activities.MainActivity" />

But as I do debug and check service is not getting called.

What's going wrong?

EDIT :

Tried this way with broadcast receiver :

public class MessageService extends Service {

ArrayList<String>  numbers = new ArrayList<>();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    numbers = intent.getStringArrayListExtra("numbers");

    for (String number:numbers) {


        sendSMS("8655864341","Hello");
    }


      //  sendMsg(numbers.get(i));


    return super.onStartCommand(intent, flags, startId);
}

public void sendMsg(final String num){
    String SENT = "SMS_SENT";
    final SmsManager sms = SmsManager.getDefault();
    final PendingIntent sentPI = PendingIntent.getBroadcast(MessageService.this, 0,new Intent(SENT), 0);
    Handler h = new Handler();
    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            sms.sendTextMessage("7303668514", null, "Hi MyApp SMS", sentPI, null);
        }
    }, 2000);
}

@Override
public IBinder onBind(Intent intent)
{

//    numbers = intent.getStringArrayListExtra("numbers");

    return null;
}

private void sendSMS (String phoneNumber, String message){
    ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>();
    ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>();
    PendingIntent sentPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
            new Intent(getApplicationContext(), SmsSentReceiver.class), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
            new Intent(getApplicationContext(), SmsDeliveredReceiver.class), 0);
    try {
        SmsManager sms = SmsManager.getDefault();
        ArrayList<String> mSMSMessage = sms.divideMessage(message);
        for (int i = 0; i < mSMSMessage.size(); i++) {
            sentPendingIntents.add(i, sentPI);
            deliveredPendingIntents.add(i, deliveredPI);
        }
        sms.sendMultipartTextMessage(phoneNumber, null, mSMSMessage,
                sentPendingIntents, deliveredPendingIntents);

    } catch (Exception e) {

        e.printStackTrace();
        Toast.makeText(getBaseContext(), "SMS sending failed...", Toast.LENGTH_SHORT).show();
    }

}


public class SmsDeliveredReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent arg1) {
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(context, "SMS delivered", Toast.LENGTH_SHORT).show();
                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(context, "SMS not delivered", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

public class SmsSentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent arg1) {
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(context, "SMS Sent", Toast.LENGTH_SHORT).show();

                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                Toast.makeText(context, "SMS generic failure", Toast.LENGTH_SHORT)
                        .show();

                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE:
                Toast.makeText(context, "SMS no service", Toast.LENGTH_SHORT)
                        .show();

                break;
            case SmsManager.RESULT_ERROR_NULL_PDU:
                Toast.makeText(context, "SMS null PDU", Toast.LENGTH_SHORT).show();
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                Toast.makeText(context, "SMS radio off", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

Getting this exception:

   java.lang.RuntimeException: Unable to instantiate receiver com.example.siddhi.contactsapp.helper.MessageService$SmsSentReceiver: java.lang.InstantiationException: class com.example.siddhi.contactsapp.helper.MessageService$SmsSentReceiver has no zero argument constructor

Not getting message..


Solution

  • You can do something like this :

    Use a for loop for your Numbers list and inside that Use a handler to maintain some time gap between each sent message, say 2 seconds and send the message.

    OR

    You can define a Broadcast Receiver inside your Service which will check for the Message Delivery Report and if Delivered then send another Message.

    First Link

    Second Link

    Hope it Helps :)

    Edit :

     @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
        ArrayList<String> numberlist=new ArrayList<String>();
    
        for(int i=0;i<numberlist.size();i++) {
    
            sendMsg(numberlist.get(i));
        }
    
        return super.onStartCommand(intent, flags, startId);
    }
    
    public void sendMsg(final String num){
        String SENT = "SMS_SENT";
        final SmsManager sms = SmsManager.getDefault();
        final PendingIntent sentPI = PendingIntent.getBroadcast(MyService.this, 0,new Intent(SENT), 0);
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                sms.sendTextMessage(num, null, "Hi MyApp SMS", sentPI, null);
            }
        }, 2000);
    }