1
I need to send a list of SMS messages. The problem is that when there are many, they seem to jam the sending, locking the function. So I’d like to send one at a time. I’m trying with the class below:
public class EnviaSMS extends AsyncTask<Object, Object, Object>
{
Activity activity;
Context context;
Sms sms;
EnviaSMS(Activity activity, Context context, Sms sms)
{
this.activity = activity;
this.context = context;
this.sms = sms;
}
@Override
protected Object doInBackground(Object... params)
{
sendSMS(sms);
return null;
}
private void sendSMS(final Sms sms)
{
String smsSent = "SMS_SENT";
String smsDelivered = "SMS_DELIVERED";
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, new Intent(smsSent), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(context, 0, new Intent(smsDelivered), 0);
// Receiver for Sent SMS.
activity.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, 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, "Generic failure", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(context, "No service", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(context, "Null PDU", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(context, "Radio off", Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(smsSent));
// Receiver for Delivered SMS.
activity.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, 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;
}
}
}, new IntentFilter(smsDelivered));
SmsManager smsSend = SmsManager.getDefault();
smsSend.sendTextMessage("6323541212".toString(), null, "Mensagem de Teste!", sentPI, deliveredPI);
}
}
When I send the SMS I can capture the return and display a Toast with Broadcastreceiver, but I can’t make the rest of the application wait for this response to call the next SMS.
Wakim, thank you for your reply. You helped me a lot. Below I put the prototype I made based on it:
public class MainActivity extends Activity
{
private Thread thread;
private int resposta = 0;
private boolean envia = true;
private int i = 1;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
thread = new Thread()
{
@Override
public void run()
{
do
{
if(envia == true)
{
envia = false;
Log.e("Sms", "Sms " + String.valueOf(i) + " enviada");
sendSMS("444444444", "Mensagem " + String.valueOf(i) + " funcionou!"); //Aqui posso substiuir por valores presentes em um array
try {
synchronized (this) {
wait(60000);
}
} catch (InterruptedException ex) {}
Log.e("Sms", "Resposta da mensagem " + String.valueOf(i) + " recebida: " + String.valueOf(resposta));
envia = true;
i++;
}
}while(i < 30); //Valor 30 para simular o envio de 30 SMS
}
};
thread.start();
}
private void sendSMS(String mobNo, String message)
{
String smsSent = "SMS_SENT";
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(smsSent), 0);
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();
resposta(1,this);
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
resposta(2,this);
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
resposta(3,this);
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
resposta(4,this);
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
resposta(5,this);
break;
}
}
}, new IntentFilter(smsSent));
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(mobNo, null, message, sentPI, null);
}
private void resposta(int res, BroadcastReceiver broadcastReceiver)
{
synchronized(thread)
{
resposta = res;
unregisterReceiver(broadcastReceiver);
thread.notifyAll();
}
}
}
In this code snippet there is no iteration. You are creating a
AsyncTask
for each message? My suggestion is to have a queue of messages inside yourAsyncTask
(only one) and within theonReceive
consume an element of that list until it ends, using await
to make theThread
wait for the shipment to be confirmed and anotify
to release theThread
for the next SMS.– Wakim