Make the application wait for the answer of a Broadcastreceiver

Asked

Viewed 532 times

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 your AsyncTask (only one) and within the onReceive consume an element of that list until it ends, using a wait to make the Thread wait for the shipment to be confirmed and a notify to release the Thread for the next SMS.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.