Reputation: 3518
I am writing module that sends messages. Module I am working on creates intent and upon message received status emits event to RN:
Messages are sent correctly and event is emitted to RN, but on each consequent call, it triggers for all previously sent messages. So for first invoke it is called once, for the second twice and so on.
Here is what I use to broadcast to RN:
private void sendEvent(String messageId) {
WritableMap params = Arguments.createMap();
params.putString("id", messageId);
this.reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("info", params);
}
Here is how I am invoking the intent:
Random generator = new Random();
Intent sentIntent = new Intent(SENT);
sentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent sentPI = PendingIntent.getBroadcast(reactContext, generator.nextInt(),
sentIntent, PendingIntent.FLAG_CANCEL_CURRENT);
reactContext.registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
sendEvent(messageId);
}
}, new IntentFilter(SENT));
As you can see I am already trying to set flags that would not use the Intent after original call. How can I make it to perform the intent once and upon sending/receiving of message cancel any future calls?
Upvotes: 2
Views: 2742
Reputation: 39181
BroadcastReceiver
instances will remain registered until you explicitly unregister them (or the registering Context
is destroyed). In this case, you're creating and registering a new instance for each send, but never unregistering any of them. Since the broadcast Intent
is always the same, after the first message, each subsequent message is going to fire not only its own newly registered instance, but also each instance registered previously.
There are a few different solutions for this.
Registering only a single Receiver instance once, before any sends begin, and unregistering it after they're all complete. The particular message results could then be distinguished by extras on the Intent
. If implementing this option, be sure that distinct PendingIntent
s are created for each, by specifying a unique requestCode
– the second argument in getBroadcast()
– for each one.
Continue registering a new instance for each send, and unregister it in onReceive()
. An extra on the Intent
can be used here also, to ensure that the correct instance is acting on a given broadcast, and is appropriately unregistered afterwards. Again, be sure that distinct PendingIntent
s are used each time.
As mentioned by the OP, similar to the second approach, continue using separate instances for each send, but use a different action String
for each; e.g., by appending an ID to a base action. As the Intent
s will then be inherently unequal, the PendingIntent
s will already be distinct, and the unique requestCode
isn't necessary.
Upvotes: 1