在日期和时间更改时重置/取消警报时的 AlarmManager 错误
Posted
技术标签:
【中文标题】在日期和时间更改时重置/取消警报时的 AlarmManager 错误【英文标题】:AlarmManager Bug while Resetting/Cancelling Alarm on Date and Time Change 【发布时间】:2012-02-25 20:24:50 【问题描述】:我想以regular
的时间间隔向服务器发送数据。所以,我同样使用AlarmManager
。它工作正常,但问题是当我cancel
Date/Time
上的警报发生变化时。那时,警报在被取消之前再次触发,这使我的应用程序变得更糟,因为extra
数据以irregular
间隔发送到server
。
这是我的BroadCastReceiver
类和AlarmManager
。
public class MyReceiver extends BroadcastReceiver
AlarmManager mgr;
PendingIntent pi;
Intent intent;
public static boolean flag = false;
@Override
public void onReceive(final Context arg0, Intent arg1)
if(arg1.getAction().equals("android.intent.action.TIME_SET"))
Log.d("MyReceiver", "Time set");
mgr = (AlarmManager) arg0.getSystemService(Context.ALARM_SERVICE);
intent = new Intent(arg0, TestService.class);
intent.putExtra("test", "testvalue");
pi = PendingIntent.getService(arg0, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if(!flag)
mgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, 5000, pi);
flag = true;
else
mgr.cancel(pi);
pi.cancel();
flag = false;
下面是带有 Logcat 输出的屏幕截图,它解释了在取消警报后,它会在取消后再次触发一次。
正如您在Logcat
输出中看到的那样,black arrow
显示了我更改取消警报的时间,red arrow
显示再次取消警报后它在取消之前触发,这是不应该发生的。那么,任何人都可以告诉我为什么会发生这种情况以及我应该怎么做restrict
警报在取消之前再次被触发。
注意:- 只有当我尝试将日期/时间从 10:00 增加到 11:00 时才会发生这种情况,当我将时间减少到 10:00 到 9:00 时效果很好。
【问题讨论】:
【参考方案1】:无法在我的最后看到 LogCat,但查看代码,我不确定,被调用的服务 (TestService) 是如何被杀死/停止的?我认为你需要以某种方式阻止它。此外,不建议在广播接收器中执行长时间运行的任务。 您是否验证了在触发 mgr.cancel(pi) 后您的服务停止事件正在发生?
【讨论】:
我没有停止服务我只是重置警报。 我猜也尝试停止服务。因为在取消警报管理器时服务可能仍在工作。 我不认为是这种情况,因为正如我所说,它只会在我增加时间时发生,而在我减少时间时工作正常。【参考方案2】:只需尝试在活动中使用一些具有待处理意图的唯一代码,然后使用相同的代码取消该意图。
在活动中设置待处理意图
PendingIntent.getBroadcast(this, code, intent, PendingIntent.FLAG_UPDATE_CURRENT);
用于停止广播接收器
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), code, intent, 0); AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(pendingIntent);
【讨论】:
【参考方案3】:为什么会这样
第一件事是您正在使用 Intent Action android.intent.action.TIME_SET
,所以这确实意味着 如果系统日期/时间发生更改,您的 BroadcastReceiver 将自动调用。
第二次你在Receiver
类中使用了一个static boolean flag
。
现在发生的事情是,每当您更改系统计时,标志就会从false to true
和true to false
切换它的状态。
这正是您的代码中发生的事情,logcat 也显示出同样的情况:一切都按照编写的代码运行。
所以在我看来,什么都没有代码和输出中发生了错误。
what should I do to restrict Alarm getting fired again before cancelling
我认为的第一件事是,您不应该像这样使用 Action TIME_SET 来打开/关闭标志,因为用户和开发人员可能不记得他们是什么更改时间以打开或关闭 FLAG,
更好的方法是, 您应该通过 Activity 自己处理服务,并在那里显示一个 ToggleButton 来管理 FLAG 的状态并设置和取消 PendingIntent。
或
如果您想自动执行您的服务的任务,您只需使用AlarmManager
并设置您的警报触发时间和间隔只有一次说时间是当前时间,间隔是 50000 毫秒..
所以它显然会从现在开始每 5 分钟调用一次服务,然后在您的应用程序中,如果用户切换它,您只需要一个 ToggelButton 来指示与服务器的同步是 On 还是 Off打开或关闭然后在您的活动中编写您的 AlarmManager 代码仅在 toggleButtontb.setOnCheckedChangeListener(listener)
中,我想 这是更好的方法然后是您实际实施的方法。
【讨论】:
我无法使用 ToggleButton,因为我的应用程序中没有任何 GUI。另外我想强制使用TIME_SET
,并在时间变化时触发一段代码。【参考方案4】:
如果您的目标只是定期在服务器上发送数据,我不明白需要设置接收器以更改日期。
更改设备的日期和时间并不意味着您的闹钟不起作用 在这些更改之前您已经设置的那个时间。
Alarmmanager
在给定的持续时间内工作,不包括设备的本地当前日期和时间。
【讨论】:
我从用户的角度考虑如果用户更改日期和时间。 如果您设置的闹钟不会取消但用户会更改它,它会保持原样 我知道它不会取消,但问题是当用户更改日期和时间时,服务第一次被多次调用。 如果您的目标只是定期在服务器上发送数据,我不明白需要设置接收器以更改日期。以上是关于在日期和时间更改时重置/取消警报时的 AlarmManager 错误的主要内容,如果未能解决你的问题,请参考以下文章