O
O
OM12016-07-10 08:18:31
Android
OM1, 2016-07-10 08:18:31

Android: how to catch Broadcasts in AsyncTask?

Hello! There is very little experience in androids, I decided to try asking here,
There is a class for async:

class CtTask extends AsyncTask<String, String, Void> {

        String SENT_SMS_FLAG = "SENT_SMS";
        String DELIVER_SMS_FLAG = "DELIVER_SMS";

        PendingIntent sentIn;
        PendingIntent deliverIn;

        BroadcastReceiver sentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent in) {
                switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        // sent SMS message successfully;
                        Toast toast = Toast.makeText(getApplicationContext(),
                                "Сообщение отправлено!", Toast.LENGTH_SHORT);
                        toast.show();
                        break;
                    default:
                        // sent SMS message failed
                        break;
                }
            }
        };

        BroadcastReceiver deliverReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent in) {
                // SMS delivered actions
                switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        // sent SMS message successfully;
                        Toast toast = Toast.makeText(getApplicationContext(),
                                "Сообщение доставлено!", Toast.LENGTH_SHORT);
                        toast.show();
                        break;
                    default:
                        // sent SMS message failed
                        break;
                }
            }
        };

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(getApplicationContext(), "onPreExecute()", Toast.LENGTH_LONG).show();

            Intent sentIn = new Intent(SENT_SMS_FLAG);
            final PendingIntent sentPIn = PendingIntent.getBroadcast(getApplicationContext(),
                    0,
                    sentIn, 0);

            Intent deliverIn = new Intent(SENT_SMS_FLAG);
            final PendingIntent deliverPIn = PendingIntent.getBroadcast(getApplicationContext(), 0,
                    deliverIn, 0);

            registerReceiver(sentReceiver, new IntentFilter(SENT_SMS_FLAG));
            registerReceiver(deliverReceiver, new IntentFilter(DELIVER_SMS_FLAG));
        }

        @Override
        protected Void doInBackground(String... urls) {

            try {
                for (String url : urls) {
                    send(url);
                    publishProgress(url);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Toast.makeText(getApplicationContext(), "onPostExecute()", Toast.LENGTH_LONG).show();
            unregisterReceiver(sentReceiver);
            unregisterReceiver(deliverReceiver);
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            Toast.makeText(getApplicationContext(), "progress: "+values[0], Toast.LENGTH_LONG).show();
        }


        private String send(String number) throws InterruptedException {
            smsManager.sendTextMessage(number, null, "text", sentIn, deliverIn);
            return "ok";
        }



    }

From the activity, I work with it like this:
ArrayList numbers = new ArrayList();
SmsManager smsManager = SmsManager.getDefault();
String[] f = (String[]) numbers.toArray(new String[0]);
CtTask catTask = new CatTask();
ctTask.execute(f);

What I have : the desired function smsManager.sendTextMessage(); is performed, in ideal conditions, sms go and come. But the essence of Broadcast for catching the status of messages does not work as it should.
Question: how to properly use Broadcast in the AsyncTask class?
Thanks for the help!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Artem Gapchenko, 2016-07-10
@artemgapchenko

Question: how to properly use Broadcast in the AsyncTask class?

Answer: no way. After the completion of the work, it is AsyncTaskimmediately beaten by the system, with the execution of the method onPostExecutein which your broadcast receivers are untied from the broadcast manager'a. And since the broadcast message may arrive BroadcastReceiverwith a delay, then it turns out that it AsyncTaskworked, the broadcast receivers got rid of, the message arrived, but there is no one to process it.
Take your broadcast receivers to the level Activity, and disable them in onPause().

O
OM1, 2016-07-10
@OM1

Ok, I'll try
UPD:
1. I register a BroadcastReceiver in an activity
2. In onPause() I cancel in the same activity
3. In an asynchronous class, in onPreExecute() I create an intent
Something like this? Anyway, something is not right ...
UPD2: It seems to have thought of it, it works on the emulator. Principle:
1. In the main activity:

protected void onResume() {
        super.onResume();
        registerReceiver(sentReceiver, new IntentFilter(SENT_SMS_FLAG));
        registerReceiver(deliverReceiver, new IntentFilter(DELIVER_SMS_FLAG));

    }


    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(sentReceiver);
        unregisterReceiver(deliverReceiver);
    }

BroadcastReceiver sentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent in) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    // sent SMS message successfully;
                    Toast toast = Toast.makeText(getApplicationContext(),
                            "Сообщение отправлено!", Toast.LENGTH_SHORT);
                    toast.show();
                    break;
                default:
                    // sent SMS message failed
                    break;
            }
        }
    };

    BroadcastReceiver deliverReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent in) {
            // SMS delivered actions
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    // sent SMS message successfully;
                    Toast toast = Toast.makeText(getApplicationContext(),
                            "Сообщение доставлено!", Toast.LENGTH_SHORT);
                    toast.show();
                    break;
                default:
                    // sent SMS message failed
                    break;
            }
        }
    };



    Intent sentIn = new Intent(SENT_SMS_FLAG);
    Intent deliverIn = new Intent(SENT_SMS_FLAG);

2. In asynchronous class:
private String send(String number) throws InterruptedException {
            TimeUnit.SECONDS.sleep(1);
            final PendingIntent deliverPIn = PendingIntent.getBroadcast(getApplicationContext(), 0, deliverIn, 0);
            final PendingIntent sentPIn = PendingIntent.getBroadcast(getApplicationContext(), 0,sentIn, 0);
            smsManager.sendTextMessage(number, null, "text", sentPIn, deliverPIn);


            return "ok";
        }

Send() is called in a protected Void doInBackground(String... urls)
The only thing I doubt is PendingIntent in a function that is called from doInBackground.
How would all this in-line business not be mixed up there?
It is still not clear how to process from which thread the BroadcastReceiver came?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question