【问题标题】:How do I check if AlarmManager has an alarm set with FLAG_ONE_SHOT如何检查 AlarmManager 是否使用 FLAG_ONE_SHOT 设置了警报
【发布时间】:2019-11-02 08:12:13
【问题描述】:

如果我使用 FLAG_ONE_SHOT 创建 PendingIntent,则后续使用 FLAG_NO_CREATE 的 PendingIntent 将返回 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");

但是,如果我将第一个待处理的意图更改为:

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

然后我的第二个 PendingIntent 没有按预期返回 null。

两个 PendingIntent 都正确设置了警报,但我无法“检查”FLAG_ONE_SHOT PendingIntent。这种行为的原因是什么?它的目的是什么?

【问题讨论】:

  • 我想你一定很困惑。是什么让您认为使用标志PendingIntent.FLAG_NO_CREATE 调用getService() 应该返回null?如果PendingIntent 不存在,它只会返回null。但是,您之前刚刚创建了PendingIntent,所以它当然仍然存在。如果您使用标志PendingIntent.FLAG_CANCEL_CURRENT,我不知道为什么它会返回null,因为这也会创建一个新的PendingIntent。请解释一下。
  • 抱歉混淆了我的 null 和 not null。使用 FLAG_NO_CREATE 它返回 null 即使 PendingIntent 存在。 FLAG_CANCEL_CURRENT 按预期工作。
  • 我还是觉得你很困惑。如果您使用FLAG_ONE_SHOT 创建PendingIntent,则此PendingIntent can only be used once. Once it is used, it will be deleted. Specifying FLAG_CANCEL_CURRENT` 将永远不会返回null,因为它将始终创建一个新的PendingIntent
  • 但是在创建 PendingIntent 之后,我会认为带有 FLAG_NO_CREATE 的 PI 应该返回该 PI(如果它正确存在)?但它只返回 FLAG_CANCEL_CURRENT PI,它从不返回 ONE_SHOT PI(而是返回 null)。对我来说,这表明 PI 不存在。但确实如此。它是用 ONE_SHOT 创建的,但它仍然存在……我说得通吗?
  • 我需要自己测试一下。

标签: android alarmmanager android-pendingintent


【解决方案1】:

我创建了一个小型测试程序来验证这种行为。如果您使用FLAG_ONE_SHOT 创建PendingIntent,然后将其传递给AlarmManager,看起来Android 会立即“消耗”PendingIntent,使其不再存在(因为它是“一次性”,它只能使用一次)。我原以为警报实际触发时会发生这种情况,但看起来情况并非如此。

你每天都会学到新东西:-)

为了解决您的问题,我将删除 FLAG_ONE_SHOT,因为您可能不需要它(只需将 0 作为“标志”参数传递)。如果您多次设置闹钟,则可以使用FLAG_UPDATE_CURRENT,如果您每次都使用不同的附加功能设置闹钟(但看起来您没有使用任何附加功能,所以您可能不需要这个)。我认为您不需要 FLAG_ONE_SHOT 来完成您正在尝试做的事情。

【讨论】:

    【解决方案2】:

    这里的问题出现是因为FLAG_ONE_SHOT 描述 PendingIntent 所以需要识别它。

    您可以使用FLAG_ONE_SHOT | FLAG_NO_CREATE 检查它的存在。 您的代码 sn-p 本质上是在检查不存在的不同 PendingIntent(没有 FLAG_ONE_SHOT),因此您会得到 null

    您也可以使用 FLAG_IMMUTABLE 进行尝试,这是另一个描述请求的 PendingIntent 的标志。

    我认为不涉及警报。

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      相关资源
      最近更新 更多