How to pass supporting objects to BroadcastReceiver in Android


almost entirely new to Android, so please don't overlook anything as "too simple"!

I'm trying to read the pressure sensor on an alarm callback (I want to collect values every ten minutes even when the device is "off" to create a barograph/storm warning).

I have managed to get the alarm to call back to a BroadcastReceiver, but that code needs the SensorManager, Sensor, and SensorEventListener, so it can request the sensor data and send the resulting callback to the handler.

I'm prohibited from passing these as constructor arguments, since a BroadcastReceiver must have a zero argument constructor (and I'm pretty sure the system makes a new receiver for each callback, since I don't pass an object, I give it the class type).

I can't add parameters to the onReceive method (obviously, or it would be an overload, and not the right method!)

I tried creating a subtype of Intent that carried extra information, but it seems that the object I register when setting the alarm is not the object that's passed into the callback.

I don't understand how I could use the Intent's get/put features, since this seems to only work with simple types or things that I think have to be serializable.

I don't really want to stuff this data into static fields of some supporting class if I can help it (it feels ugly to say the least, but if this is what's expected, well, so be it).

I assume it's not a terribly efficient approach to go find the sensor manager and sensor every time this handler is called (it would not be a performance issue in this case, since I only want to get the pressure data at long intervals, but it seems wrong in the general case). Even if I did that, I don't understand how I could find my SensorListener.

Can someone point me in the right direction? This, I assume, is something fundamental about how an Android app's architecture is supposed to be structured, but as a beginner the docs are more than a little overwhelming and I have gone round in circles several times but don't even know what terminology I might be looking for. I've found some examples but they've either been so simple they don't address the problem (e.g. they just log that the alarm went off) or they're so complex I can't see the wood for the trees.

Thanks in advance for any pointers, Toby.

2
Jul 10 at 6:19 PM
User AvatarToby Eggitt
#android#broadcastreceiver#android-broadcast

Accepted Answer

A BroadcastReceiver is an entry point to your app. In particular, it is a very lightweight entry point. onReceive() needs to complete its work in a few milliseconds to not cause problems, and (depending on how you have set it up) the BroadcastReceiver object may be garbage-collected shortly after onReceive() ends. Your entire process might be terminated shortly after onReceive() ends.

A broadcast can be a trigger to arrange for work to be done, but usually the BroadcastReceiver itself is not doing the work.

A relatively safe modern solution is to use WorkManager:

  • onReceive() of your BroadcastReceiver schedules work to be performed by WorkManager

  • Your Worker has a longer window of time, measured in a few minutes, to do its work (register for the pressure sensor callback, get the sensor reading, write it to disk/send it to a server/whatever you're doing with the reading, and clean up)

> I assume it's not a terribly efficient approach to go find the sensor manager and sensor every time this handler is called

You don't have much of a choice. Your process is not guaranteed to exist between alarms, or between an alarm and a scheduled bit of WorkManager work. Relatively speaking, obtaining a SensorManager and registering a listener is fairly cheap.

User AvatarCommonsWare
Jul 10 at 6:48 PM
2