Reliable message processing with WakefulBroadcastReceivers
Pro-tip by +Joanna Smith
A common pattern used to process an incoming broadcast is for your BroadcastReceiver to start a service, often times an IntentService, to process the message. But what if that processing never happened?
I ran into this when I was using Google Cloud Messaging to deliver severe weather alerts to affected devices in a weather app: the message would be received and yet the notification wouldn’t fire. Tracing the bug led me to the following scenario:
The device would be idle, just chilling, doing it’s thing on the tabletop, while the screen was off. Then I would send the weather message to the GCM servers, which would pass it along to my device. This causes the device CPU to wake up and trigger onReceive().
The onReceive() method would then get excited to be called up to do its job, and so it would call startService() to trigger my IntentService. But in that moment between onReceive() finishing its work and the IntentService beginning, the CPU was being super protective of my device battery and was going back to sleep. This didn’t happen every time, but only occasionally. And it left me sitting there, staring at my device and wondering where my alert was!
And this, my friends, is the exact reason we created the WakefulBroadcastReceiver
, a BroadcastReceiver that automatically creates a partial wakelock. So in onReceive(), instead of calling startService(), now I call startWakefulService()
, and the system will take care of acquiring and holding the wakelock for me while my IntentService does its job, preventing the device from falling back asleep. Then, when the service is finished, I call completeWakefulIntent()
to let the system know that it can release the wakelock because I’m done building my notification.
So, you may be wondering why would anyone ever use a BroadcastReceiver if the super cool WakefulBroadcastReceiver exists. And honestly, it comes down to your use case. How critical is your response to a message? If you are expecting immediate action, like a severe weather notification so that your users are informed of potential danger, you want to depend on that wakelock. But if your response is only relevant while the user is active on their device, you don’t need to worry, and you can stick with the classic BroadcastReceiver.
For more information on receivers, you can check out Managing Device Awake State: https://goo.gl/hU5tiR
 - https://goo.gl/GIjGvH#BuildBetterApps