This question brought up an interesting issue.
The OP has an app that displays a map, and this map needs to be updated with location markers that are received via SMS messages. The individual steps are fairly straightforward: the SMS messages can be received by a BroadcastReceiver, the markers can be displayed by an ItemizedOverlay on top of a MapView. The tricky part is to have the receiving part communicate with the main part of the app.
What happens if the app has an active MapActivity, and then its BroadcastReceiver is invoked as a response to an incoming SMS? Is the MapActivity suspended while the BroadcastReceiver code is executed in the same process? If so, is it safe for BroadcastReceiver to access the MapActivity via a static reference (which is set by the activity's onCreate method?
Conversely, is an app's BroadcastReceiver executed in a separate process, and would therefore need some other way to communicate with the app's activty?
Reading the docs, it looks like a BroadcastReceiver is executed on a different process, tho I'm not 100% sure (BroadcastReceiver lifecycle)
A process that is currently executing a BroadcastReceiver (that is, currently running the code in its onReceive(Context, Intent) method) is considered to be a foreground process
This said, I wouldn't consider safe to access the activity from the onReceive, as it's a different process and it will probably crash.
Take into account that the Activity can also act as a BroadcastReceiver, tho you have to control when in its lifecycle it actively listens for events. That way, you can subscribe in onResume (code extracted from ZXing project)
public void onResume(){
activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
[...]
}
public void onPause() {
[...]
activity.unregisterReceiver(powerStatusReceiver);
}
And you define the BroadcastReceiver as a private class inside the public class
final class InactivityTimer {
[onResume, onPause, rest of the stuff ...]
private final class PowerStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
// 0 indicates that we're on battery
// In Android 2.0+, use BatteryManager.EXTRA_PLUGGED
int batteryPlugged = intent.getIntExtra("plugged", -1);
if (batteryPlugged > 0) {
InactivityTimer.this.cancel();
}
}
}
}
}
So, the BroadcastReceiver should always persist the new markers (through a Service, never inside the onReceive) AND it should notify a potentially active MapActivity that new markers have been added, which will be listening if it's active.
Or, even easier, the Activity and the BroadcastReceiver listen for the same SMS Intent. While the latter persists it, the first updates the map, tho I'm just guessing what I would try.
The BroadcastReceiver should run in the same process. BroadcastReceiver is designed to be short-lived. As such it can execute without any real worry about suspending the foreground Activity. You could potentially access the Activity directly via static reference assuming you checked for the case where the Activity has not yet been created. However, it might make more sense to communicate via Intents.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With