Search code examples
javaandroidbroadcastreceiveralarmmanager

How to have more than one instance of the same broadcast running simultaneously


I've been stuck for 3 days now, either what I want to do is incredibly basic or incredibly complicated becasue I can't seem to find an answer anywhere. I have a BroadcastReceiver and a button that sends an intent to start that broadcast, each time I click the button it sends diffrent data (int++), the intent has a timer of 10m, so I have two problems:

1: To send the data I have to use sendBroadcast(intent) but to set the timer I have to use an AlarmManager, and just putting the data into the intent and the intent into the AlarmManager makes it always send the first data that was inserted, how do I fix this?

2: I want to have more than one instance of the same BroadcastReceiver with Alarms counting simultaneously without interfering with each other. Case example: the user creates 1 alarm and 5m later he creates another one, what's happening is only one alarm gets executed 10m after he set the 2nd one, overriding the first one, the intended result is to execute the 1st alarm 10m after he set the 1st one and execute the 2nd one after he set the 2nd one, how do i achieve this?

My broadcastReceiver:

public class Broadcast_RemoveClass extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int i = intent.getExtras().getInt("mInt");
            Toast.makeText(context, "done"+i, Toast.LENGTH_LONG).show();
        }
    }

Sending the intent inside onClick:

public void startAlert(int i) {
    Intent intent = new Intent(getActivity(), Broadcast_RemoveClass.class);
    Bundle bd = new Bundle();
    bd.putInt("mInt", i);
    intent.putExtras(bd);
    // getActivity().sendBroadcast(intent);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity().getApplicationContext(), 0, intent, 0);
    AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 60 * 10, pendingIntent);
    Toast.makeText(getActivity(), "countdown started " ,Toast.LENGTH_SHORT).show();
}

Guys please help, even if it's just to one of the questions


Solution

  • When you do:

    PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity().getApplicationContext(), 0, intent, 0);
    

    the first 0 acts as an id for this pending intent. This way you can cancel it or update it in the future. If you send another pending intent to the system with the same id (and the appropriate flag) it replaces the previous one. So post your new pending intent using a different id. You use a hardcoded 0 for all cases....

    This behaviour is also controlled by the flag that is set in the end.You have set this value to 0. This is pointless...There is no public static final field in the PendingIntent class with 0 value. Never use hardcoded values for flags. Even if they have a valid value they make your code extremely confusing. Replace the 0 in the end with the appropriate flag depending on what you want to do. The available flags in the PendingIntent class are these:

    int FLAG_CANCEL_CURRENT
    Flag indicating that if the described PendingIntent already exists, the current one should be canceled before generating a new one.
    int FLAG_IMMUTABLE
    Flag indicating that the created PendingIntent should be immutable.
    int FLAG_NO_CREATE
    Flag indicating that if the described PendingIntent does not already exist, then simply return null instead of creating it.
    int FLAG_ONE_SHOT
    Flag indicating that this PendingIntent can be used only once.
    int FLAG_UPDATE_CURRENT
    Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent.
    

    You don't need a second instance of the broadcast receiver. The same broadcast receiver can handle all the intents you want.