Let me start by admitting that I am learning (or struggling to learn) Android, while also doing something that appears to be somewhat challenging.
While I think I have understood the basic usage of BroadcastReceivers and I can use one to receive SMS's and do some processing, I would like for this processing to happen even when device goes to sleep. Reading around, and asking a question (this one), I understand that I need to acquire a PARTIAL wake lock (to keep the CPU active, while screen+keyboard are asleep), to process the incoming SMS requests, much in the way the main Messaging application (or say Hangout or other general messaging apps) that can receive the incoming SMS and flash the notification LED and vibrate (if configured to do so).
However, what I am confused about is the following:
- Wake lock has to be acquired when work is to be done, and released when there is no work to be done. If wake lock is acquired and never released, you drain battery much faster.
- If the above is true, then how is a SMS reading application is expected to be immediately notified (perhaps using a BroadcastReceiver) of the incoming message, while not having to acquire the wake-lock permanently ?
- One way that comes to my mind is, to use a Service that mostly sleeps, and only periodically wakes up, to check if there are any SMSs. However, this is contrary to the logic that the incoming SMS and it's corresponding Broadcast Intent could happen any time, clearly with ample opportunity for the application to miss the broadcast.
So, how can one develop an application that:
- Never misses, any incoming SMS, and hopefully is notified as soon as it arrives (even when device is otherwise sleeping)
- Consumes minimum battery, especially since the processing of the SMS Broadcast Intent is very small and simple... computationally minimal.
Edit (12-Sept-2014)
While I've accepted the answer, I wanted to add what I understood, although I am still not 100% sure that my understanding is correct.
What I understood is that, at a low level (operating system, firmware and device HW), in an Android device, when the device goes to sleep, there are multiple events that can cause it to 'wake up'. Network events, keyboard events, some (if not all) sensor events, timer events etc. will cause the device to wake up, and quickly process the event, and try it's best to go back to sleep ASAP. As I understand, the last bit is the key. This means, that events like incoming-call, incoming SMS, keypress or other causes that result in a Broadcast Intent, always lead to an Intent to be generated and delivered to all registered BroadcastReceivers. This part is ensured. However, what is not ensured is that all BroadcastReceivers would get enough time, to spend as much time as they need to process the Intent. Instead, they need to acquire a Wake lock (of the appropriate kind) and ensure that the device doesn't go back to sleep until the Wake lock is released. Now, as I realize, there are multiple ways of acquiring the Wake lock. It could be done directly in the BroadcastReceiver, but apparently not always intuitive as to what is the best and most efficient way to manage it, s.t. it is held for the least amount of time and released as soon as it is not required. For this the SDK provides the 'WakefulBroadcastReceiver' mechanism, making the task of writing software that handled BroadcastIntent simpler when holding a wake-lock is necessary. Then there is the alternative called WakefulIntentService, developed by CommonsWare (unless I am not mistaken, it is not from the SDK, but 3rd party).
I hope I am right :)
Edit (13-Sept-2014)
More information available in this SO Q&A