Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to unregister 'anonymous' BroadcastReceiver

I recently asked a question about checking on the state of a sent SMS and the answer given was a code snippet which registered two 'anonymous inner' (please correct my terminology if it is incorrect) BroadcastReceivers to listen for SMS sent/delivered broadcasts. These receivers were only required to receive data regarding the SMS my application had just sent, so were not required to listen permanently.

My immediate thought was "well, I'll need to unregister them after I've finished with them", but is this correct? I asked the poster this as he hadn't included any unregister code, but got no reply. The code seems to be a pretty standard way of doing what I want as it appears on numerous Android dev sites. Here it is:

//---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);

The code works fine.

What's more, it does not get notified of any SMS sent/delivered events which occur external to my app. E.g. I can send an SMS after these BroadcastReceivers have been registered and not see any Toast messages.

So, I have two questions:

  1. do I need to unregister these BroadcastReceivers?
  2. If not, why not?
like image 657
barry Avatar asked Nov 04 '22 22:11

barry


2 Answers

Simply save your BroadcastReceiver to an instance so you are able to unregister it ;-)

Just change this line from:

registerReceiver(new BroadcastReceiver(){

to:

BroadcastReceiver smsReceiver=new BroadcastReceiver(){...}
registerReceiver(smsReceiver);

Later you can execute than:

unregisterReceiver(smsReceiver);

Just remember to save the smsReceiver as a class member.

like image 165
rekire Avatar answered Nov 10 '22 10:11

rekire


What's more, it does not get notified of any SMS sent/delivered events which occur external to my app.

You are dynamically registering receivers. If you want to listen to intents from other applications, you need to register your receiver in the manifest file. That way it will be always active. And you won't need to unregister it.

like image 34
Stashi Avatar answered Nov 10 '22 10:11

Stashi