Pending intent with ONE_SHOT flag

14,114

Yes, of course you can create it again. You will get a different PendingIntent from the first one.

However, there are a few problems with the code you've posted. First of all, you create the PendingIntent like this:

    pendingIntent = PendingIntent.getBroadcast(context,
            PENDING_INTENT_RETRY, myIntent, PendingIntent.FLAG_ONE_SHOT);

but you check if it exists like this:

    pendingIntent = PendingIntent.getBroadcast(context,
            0, myIntent, PendingIntent.FLAG_NO_CREATE);

This check will always return null because you are using a different requestCode! When you create the PendingIntent you pass PENDING_INTENT_RETRY as requestCode, but when you check if it exists you pass 0 as requestCode.

The second problem is the way FLAG_ONE_SHOT works. If you create a PendingIntent using FLAG_ONE_SHOT and then try to get a PendingIntent using FLAG_NO_CREATE, it will always return null, even if the PendingIntent has not yet been used! Because of this behaviour, you cannot use FLAG_NO_CREATE to determine if an alarm is pending, if you have set that alarm using a PendingIntent created with FLAG_ONE_SHOT.

If you really want to use this architecture, then you cannot use FLAG_ONE_SHOT. Just create the PendingIntent normally (without flags) and check for its existence using FLAG_NO_CREATE.

Share:
14,114
greywolf82
Author by

greywolf82

What can I say? The only thing I know is that I don't know everything.

Updated on June 04, 2022

Comments

  • greywolf82
    greywolf82 about 2 years

    Currently I've got this code:

    public static void setupAlarm(Context context) {
            Intent myIntent = new Intent(context, Receiver.class);
    
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                    0, myIntent, PendingIntent.FLAG_NO_CREATE);
            if (pendingIntent != null) {
                return;
            } else {
                pendingIntent = PendingIntent.getBroadcast(context, PENDING_INTENT_RETRY, myIntent,
                        PendingIntent.FLAG_ONE_SHOT);
            }
    
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.add(Calendar.MINUTE, 2);
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
        }
    

    What I want is to use pending intent one time and wait for the fire. If in the meantime someone asks for a new alarm, if the alarm exist I don't want to setup anything. Now my question: after the first alarm, the pending intent is deleted due to the ONE_SHOT flag, but can I create the pending intent again or not?

  • M-Wajeeh
    M-Wajeeh over 4 years
    "To retrieve an existing PendingIntent created with FLAG_ONE_SHOT, both FLAG_ONE_SHOT and FLAG_NO_CREATE need to be supplied." developer.android.com/reference/android/app/PendingIntent
  • David Wasser
    David Wasser over 4 years
    @M-WaJeEh Very interesting. I wonder if that is something newly added to the documentation as I don't ever remember seeing that. Answers some previous confusion of course. Thanks for that Info!