我有一个闹钟应用程序,当它停止并激活时,闹钟仍然会在设定的时间播放。当用户返回应用程序时,他/她可以看到闹钟上剩余的剩余时间。
我用来设置闹钟剩余时间的方法和变量是使用pendingIntent和Alarm Manager以及System.currentTimeMillis();
一切都很好。如果时间是例如: 上午10点,我设置闹钟在上午10:40设置,然后有一个倒计时器,显示在TextView的帮助下剩下的时间,这是40分钟,它向下计数,直到它达到0。已达到0警报被召唤。
但是,如果用户转到智能手机中的设置应用程序并将系统时间更改为上午9:00,则警报处于活动状态。然后,如果我返回到警报应用程序,Textview显示还剩100分钟。从上午10:40到上午9:00 = 100分钟差异。
我想防止这种情况发生。有没有办法可以阻止用户在闹钟激活时更改系统时间,还是有其他解决办法?
我试图做的是查看System.currentTimeMillis();在onStart();小于savedprefs System.currentTimeMillis();来自onStop。如果它少了,那么我想要立即调用警报。
然而,为了使其正常工作,用户必须在更改系统时间后返回警报应用程序,如果用户不返回则不会工作。
任何解决方案?
答案 0 :(得分:1)
嗯,你不想告诉别人不要改变他的电话时间。这不是他的选择;)
此外,如果用户将闹钟设置为10:40并且他说时间是9:00,那么确实还有100分钟。例如,我必须在7点醒来工作并设置闹钟但是我注意到我的时间提前1小时。我在手机上移回时间,但我仍然想在7点起床,因为那时我必须去上班,警报间隔增加。
因此,正确的行为不是将其称为警报(基于时间),而是基于剩余时间的计时器。例如,如果您从现在开始设置计时器40分钟,那么无论当前时间是什么,通知都会在40分钟后完成。
为此,您需要将倒数计时器设置为特定的时间间隔,而不是取决于系统时间。您仍然可以使用系统时间进行初始计算,但是对于后续计算,您不应该这样做。因此,例如,如果初始计算告诉您警报应该在30分钟后发生,您可以执行以下操作:
long initialTimeLeft= calculateTheTimeFromSystemTime(); // you write that ;)
new CountDownTimer(initialTimeLeft, 1000) {
public void onTick(long millisUntilFinished) {
broadcastRemainingTime();
}
public void onFinish() {
broadcastTimerHasFinished();
}
}.start();
这可能会按预期工作;)时间不依赖于第一次迭代后的系统时间。
还有另一个问题,你可能会遇到这样的问题。为了解决此问题,您需要将该计时器作为服务启动,并在倒计时结束时sendBroadcast()
并在主应用程序中创建BroadcastReceiver
以接收该广播并打开音乐(或者你的警报做什么)。在onTick()事件中,您可以广播剩余时间,并且在您的应用程序中,您可以接收该广播并获得剩余时间。
您不希望更新onStart()中的时间并进行更多计算。一旦你启动了计时器并且它作为一项服务工作,让它处理时间计算,在你的主要活动中只需要担心显示剩余时间(从计时器广播中获取)并在警报触发时执行某些操作(也可以获得)它来自计时器广播)
如果您不使用计时器作为服务,那么您可以计算剩余时间:
long timeLeftInMillis=initialTime;
timer = new CountDownTimer(initialTime, 1000) {
@Override
public void onTick(long millisecondsUntilFinished) {
timeleft = millisecondsUntilFinished;
}
}
为了对广播服务做同样的事情,它将是:
Intent bi = new Intent("ALARM_COUNTDOWN_INCOMING!");
public void onTick(long millisecondsUntilFinished) {
bi.putExtra("timeleft ", millisUntilFinished);
sendBroadcast(bi);
}
在主要活动中:
private BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long timeLeft = intent.getLongExtra("timeLeft ", 0);
//Update the text view with that timeLeft
}
};