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:
- do I need to unregister these
BroadcastReceivers
? - If not, why not?
You will need to unregister. Else, it will most probably crash. I am quite sure about it. But if you say that it's not crashing, then, well, need to look into it :)
Because, Android will think you forgot to unregister. It expects you to unregister. "Note: If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won't receive intents when paused, and this will cut down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack." <===== From the docs