【问题标题】:Pending intent with different intent but same ID具有不同意图但 ID 相同的待处理意图
【发布时间】:2016-08-04 04:19:59
【问题描述】:

我有两个待定意图与警报管理器一起使用,一个是:

Intent i = new Intent(context, TriggerAlarm.class);  
PendingIntent pi =PendingIntent.getBroadcast(context,0,i,PendingIntent.FLAG_CANCEL_CURRENT);

另一个是:

 Intent i = new Intent(context, TriggerNotification.class);
 PendingIntent pi = PendingIntent.getBroadcast(context,0, i,PendingIntent.FLAG_CANCEL_CURRENT);

我在我的应用程序中以不同的方法使用这两个

我的问题是:

这些pendingIntents彼此不同吗?因为意图不同但ID相同

如果我为这些待处理意图中的每一个设置警报管理器,它们会触发还是替换另一个?

【问题讨论】:

  • 您可以在不同的方法中为多个实例使用相同的 id,因为每个 id 的范围将只是方法体,但是当您从外部访问它时,它将取决于运行时可访问性作为哪个实例系统调用,因此它将执行下一个任务
  • 你的意思是他们不一样?
  • 下载文档:The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

标签: android alarmmanager android-pendingintent


【解决方案1】:

所以最简单的方法是自己直接测试。 我已经在我的电脑上测试了它,这是我得到的:

这些pendingIntent 是否彼此不同?因为意图不同但ID相同

-是的,尽管 ID 相同,但它们彼此不同

如果我为这些待处理意图中的每一个设置警报管理器,它们会触发还是替换另一个?

-两者都会触发

这是我的测试代码,大家可以自己复制试试

将此方法复制到您的活动中,然后调用它

private void setAlarmManager() {
    Log.v("AlarmManager", "Configuring AlarmManager...");
    Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
    PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, PendingIntent.FLAG_CANCEL_CURRENT);

    Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
    PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, PendingIntent.FLAG_CANCEL_CURRENT);

    AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.SECOND, 20);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        Log.v("AlarmManager", "Starting AlarmManager for >= KITKAT version");
        alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
        alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
    } else {
        Log.v("AlarmManager", "Starting AlarmManager for < KITKAT version");
        alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
        alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
    }

    Log.v("AlarmManager", "AlarmManager has been started");
}

创建你的第一个接收器类

public class AlarmReceiverFirst extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v(this.getClass().getSimpleName(), "first alarm receiver is called");
    }
}

创建你的第二个接收器类

public class AlarmReceiverSecond extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v(this.getClass().getSimpleName(), "second alarm receiver is called");
    }
}

将这些接收器注册到您的清单中

<receiver android:name=".AlarmReceiverFirst" />
<receiver android:name=".AlarmReceiverSecond" />

不要混淆,这里你所说的Id就是请求码。它用于取消待处理的意图。

【讨论】:

  • 感谢您的回复,我自己也测试过,但我想要一个确定的答案,无论如何谢谢
  • 如果我在这种情况下只使用一个 AlarmReceiver 类会怎样?
  • @JimmyTrivedi 是的,您只能将单个AlarmReceiver 类用于不同的PendingIntents,但请确保请求代码是唯一的,因此每个PendingIntent 将始终调用AlarmReceiver 类。否则AlarmReceiver 类只调用一次。
  • @HendraWD 这就是问题所在。我想为同一个 ID 做
  • @JimmyTrivedi 如果您希望创建的每个PendingIntent 始终调用AlarmReceiver,请使用不同的请求代码。否则使用相同的请求代码,它将用相同的请求代码覆盖之前的PendingIntent。我希望我的解释足够清楚。
【解决方案2】:

Intent 只是 PendingIntent 触发后必须执行的操作。但是这个触发条件完全依赖于PendingIntent本身,RequestCode在这里起到了很好的作用,可以唯一识别、管理和触发PendingIntent。

因此,无论Intent是什么,如果requestCode被重复,那么后面的PendingIntent都会触发。如果需要触发多个PendingIntent,则requestCode必须互不相同。

【讨论】:

    【解决方案3】:

    您可以使用相同的意图名称,但使用不同的 ID,如以下,

    Intent i = new Intent(context, TriggerAlarm.class);  
    PendingIntent pi =PendingIntent.getBroadcast(context,System.currentTimeMillis(),i,PendingIntent.FLAG_CANCEL_CURRENT);
    

    还有

    Intent i = new Intent(context, TriggerNotification.class);
    PendingIntent pi = PendingIntent.getBroadcast(context,System.currentTimeMillis(), i,PendingIntent.FLAG_CANCEL_CURRENT);
    

    这样,两种意图的区别就会不同,并且会被触发。您可以使用任何唯一的 id 而不是 System.currentTimeMillis()

    【讨论】:

    • 在我的情况下,我有两个表数据库,一个用于警报,另一个用于通知,我使用每个 id(自动增量)作为待处理 Intent 的 Id,并且这些 id 可能相互冲突!因为有两张桌子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多