Here is a simple and elegant solution for having multiple broadcast receivers listen on the same intent in the same app. Although I didn’t test not using this method in my apps, your broadcast receivers might consume the intent if more than one are listening separately. If you’re facing with this problem here is a workaround for it, a code snippet inspired by the way Admob for android seems to solve this, as shown in their documentation, using meta-data in manifest file…


 

  • Choose a Broadcast receiver to be the one who will get the broadcasted intent and use it to pass the intent to other broadcast receivers. You’ll need to have access to the code of the first one.
  • In your manifest file declare the first receiver as normally and put the others as meta-data between this receiver’s tags. No need to declare the receivers separately. I’ll use as code examples the class from this article.
ReferrerCatcher"
          android:exported="true">
   <intent-filter>
      <action android:name="com.android.vending.INSTALL_REFERRER"></action>
   </intent-filter>
   <meta-data android:name="forward.GoogleAnalytics"
              android:value="com.google.android.apps.analytics.AnalyticsReceiver" />
</receiver>
  • Notice the meta-data tags. Attribute android:name choose any distinctive string value you want.Attribute android:value should be the full name of the other broadcast receivers classes, including package.
  • The code for ReferrerCatcher receiver is the same as described in this article. All you have to do is add the following code in the onReceive method.
//get receiver info
ActivityInfo ai = context.getPackageManager().getReceiverInfo(new ComponentName(context, "my.package.ReferrerCatcher"), PackageManager.GET_META_DATA);
//extract meda-data
Bundle bundle = ai.metaData;
Set<String> keys = bundle.keySet();
//iterate through all metadata tags
Iterator<String> it = keys.iterator();
while(it.hasNext()){
  String k = it.next();
  String v = bundle.getString(k);
  ((BroadcastReceiver)Class.forName(v).newInstance()).onReceive(context, intent); //send intent by dynamically creating instance of receiver

  Log.i("PASS REFERRER TO...", v);
}

In other words, we extract meta-data, iterate through it and by creating dynamically and instance of the corresponding Broadcast receiver, we pass the intent to its onReceive method.

About these ads