我正在编写一个Android应用程序,用户可以选择多个股票进行观察,并在预定义的警报条件匹配时收到警报。库存数据保存到自定义Parcelable类“alert”的5个对象(每个库存和条件一个对象)。定期数据更新是通过AlarmManager启动的服务完成的。警报对象通过将它们放入Intent进入服务,该Intent被放入AlarmManager的PendingIntent中。
Intent intent = new Intent(this, UpdateService.class);
Bundle b = new Bundle();
saveAlertsToBundle(b);
intent.putExtras(b);
intent.setData(Uri.parse("updateManager"));
PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0);
// 1min intervall
long intervall = DateUtils.MINUTE_IN_MILLIS * 1;
// time of first start
long firstStartDelay = DateUtils.SECOND_IN_MILLIS * 30;
long firstStart = System.currentTimeMillis() + firstStartDelay;
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// kill running
am.cancel(pendIntent);
//start new
am.setRepeating(AlarmManager.RTC_WAKEUP,firstStart,intervall,pendIntent);
我的问题是:
当第一次启动服务时,只有一个警报对象传递给服务,一切正常。一旦存在更多警报对象,它们也需要传递给服务,但这不适用于上面的代码。该服务不会使用其他警报对象接收更新的意图,而只会接收仅具有一个警报对象的初始意图。上面的代码正确地创建了一个包含额外警报对象的Intent,但它们从未进入该服务。
所以我的问题是,如何将更新后的意图传递给已经运行的AlarmManager。
我已经尝试停止AlarmManager(// kill运行注释中的行)并重新启动它,但这不起作用。也许是因为意图没有像他创建时那样保持相同的警报对象?我尝试通过在意图的数据部分设置uri来解决这个问题,但这也无济于事。
感谢您的帮助。
答案 0 :(得分:2)
您的问题是PendingIntent
的工作方式。系统管理PengingIntent
s池。代码执行时:
PendingIntent pendIntent = PendingIntent.getService(this,0,intent,0);
这会导致系统搜索与您传入的参数相匹配的PendingIntent
(在本例中为Intent
。但是,PendingIntent
仅使用的匹配算法比较Intent
的某些字段,以确定它是否是您要查找的字段。特别是不会比较额外内容。这意味着您创建了第一个{ {1}},对PendingIntent
的调用将始终从池中返回相同的PendingIntent.getService()
(而不是创建一个新的,这是您想要的)。
为了在每次调用时调用PendingIntent
创建一个新PendingIntent.getService()
,请尝试将传递给调用的参数设为唯一,如下所示:
PendingIntent
由于对int requestCode = (int) System.currentTimeMillis(); // Create unique request code
PendingIntent pendIntent = PendingIntent.getService(this, requestCode, intent, 0);
的每次调用requestCode
都不同,这可以解决您的问题。
编辑基于OP的评论
您想取消现有警报并使用新数据创建新警报。在这种情况下,您不需要使用唯一标识符,因为您只希望在池中有一个PendingIntent.getService()
。但是,您想要更改数据。试试这个:
PendingIntent