If you only have 2 objects that might handle your broadcast (in your case an Activity and a notifications controller), you can achieve the behavior of a ordered broadcast using only the LocalBroadcastManager.
The general idea is:
- Set up your Service so that it broadcasts an Intent to your Activity with a particular action when you want to display your result
- In your Activity create a BroadcastReceiver that handles your Service result Intent, and register it on the LocalBroadcastManager with an IntentFilter using the action from step 1
- In your Service, when the results are available, try to send the result Intent using LocalBroadcastManager.getInstance(Context).sendBroadcast(Intent) this method returns a boolean that indicates if the broadcast has been sent to at least one receiver. If this boolean is false, it means that your Activity didn't handle your broadcast and you should show a notification instead.
In your service:
public UnzipService extends IntentService {
public static final String ACTION_SHOWRESULT = UnzipService.class.getCanonicalName() + ".ACTION_SHOWRESULT";
@Override
protected void onHandleIntent(Intent intent) {
Thread.sleep(500); // Do the hard work
// Then try to notify the Activity about the results
Intent activityIntent = new Intent(this, YourActivity.class);
activityIntent.setAction(ACTION_SHOWRESULT);
activityIntent.putExtra(SOME_KEY, SOME_RESULTVALUE); // Put the result into extras
boolean broadcastEnqueued = LocalBroadcastManager.getInstance(this).sendBroadcast(activityIntent);
if (!broadcastEnqueued) { // Fallback to notification!
PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
.notify(SOME_ID, new NotificationCompat.Builder(this)
.setContentIntent(pendingIntent)
.setTicker("results available")
.setContentText("results")
.build());
}
}
}
In your Activity:
public YourActivity extends Activity {
private BroadcastReceiver resultReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
processResult(intent); // Results Intent received through local broadcast
}
}
private IntentFilter resultFilter = new IntentFilter(UnzipService.ACTION_SHOWRESULT);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
Intent intent = getIntent();
if (UnzipService.ACTION_SHOWRESULT.equals(intent.getAction())) {
// The Activity has been launched with a tap on the notification
processResult(intent); // Results Intent contained in the notification PendingIntent
}
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this)
.registerReceiver(resultReceiver, resultFilter);
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(resultReceiver);
super.onPause();
}
private void processResult(Intent intent) {
// Show the results from Intent extras
}
}
This should be a complete working example.
I hope this helps who is trying to implement ordered broadcasts with LocalBroadcastManager from support library!
<intent-filter>
on my broadcast receiver in the manifest, but i thought it needed that?<receiver android:name=".DataLoadReceiver"> <intent-filter> <action android:name="com.something.something.DATALOADRECEIVER" /> </intent-filter> </receiver>
– Argybargy