How do I check if AlarmManager has an alarm set with FLAG_ONE_SHOT

北城余情 提交于 2019-12-23 02:30:58

问题


If I create a PendingIntent with FLAG_ONE_SHOT, a subsequent PendingIntent with FLAG_NO_CREATE returns null.

    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context,AlarmService.class);
    PendingIntent pi = PendingIntent.getService(context,this.getId(),intent,PendingIntent.FLAG_ON_SHOT);
    GregorianCalendar alarmtime = new GregorianCalendar(now.get(GregorianCalendar.YEAR),now.get(GregorianCalendar.MONTH),now.get(GregorianCalendar.DAY_OF_MONTH),0,0);

    //Set the alarm
    if (Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT) {
        am.set(AlarmManager.RTC_WAKEUP,alarmtime.getTimeInMillis(), pi);
    } else {
        am.setExact(AlarmManager.RTC_WAKEUP, alarmtime.getTimeInMillis(), pi);
    }

    //Now check if the alarm was set, if it was set, the following PendingIntent should return not null but it doesn't
    PendingIntent piCheck = PendingIntent.getService(context,this.getId(),intent,PendingIntent.FLAG_NO_CREATE);

    if (piCheck!=null) {
        Log.d(TAG,"piCheck returned NOT NULL and probably returned pi");
    } else if (piCheck==null) {
        Log.d(TAG,"piCheck returned NULL pi does not exist");

However if I change the first pending intent to:

PendingIntent pi = PendingIntent.getService(context,this.getId(),intent,PendingIntent.FLAG_CANCEL_CURRENT);

Then my second PendingIntent returns not null as expected.

Both PendingIntents set an alarm properly, but I cannot "check" the FLAG_ONE_SHOT PendingIntent. What is the reason for this behaviour? What is the purpose of it?


回答1:


I created a small test program to verify this behaviour. If you create a PendingIntent using FLAG_ONE_SHOT and then pass this to the AlarmManager, it looks like Android "consumes" the PendingIntent immediately so that it no longer exists (because it is a "one-shot", it can only be used once). I would have thought this would happen when the alarm actually triggers, but it looks like that isn't the case.

You learn something new every day :-)

To solve your problem, I would just remove the FLAG_ONE_SHOT as you probably don't need it (just pass 0 as the "flags" argument). If you set the alarm more than once, you can use FLAG_UPDATE_CURRENT if you set the alarm with different extras each time (but it looks like you aren't using any extras, so you probably don't need this). I don't think that you need FLAG_ONE_SHOT for what you are trying to do.




回答2:


The problem here arises because FLAG_ONE_SHOT describes the PendingIntent and so will be needed to identify it.

You can check for its existence by using FLAG_ONE_SHOT | FLAG_NO_CREATE. Your code snippet is essentially checking for a different PendingIntent (one without FLAG_ONE_SHOT) which doesn't exist and hence you get null.

You can also try this out with FLAG_IMMUTABLE which is another flag that describes the requested PendingIntent.

I don't think that alarms are involved.



来源:https://stackoverflow.com/questions/27763646/how-do-i-check-if-alarmmanager-has-an-alarm-set-with-flag-one-shot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!