阻止/使用户无需更改设置中的时间

时间:2018-04-27 07:33:58

标签: java android-studio time

我有一个闹钟应用程序,当它停止并激活时,闹钟仍然会在设定的时间播放。当用户返回应用程序时,他/她可以看到闹钟上剩余的剩余时间。

我用来设置闹钟剩余时间的方法和变量是使用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。如果它少了,那么我想要立即调用警报。

然而,为了使其正常工作,用户必须在更改系统时间后返回警报应用程序,如果用户不返回则不会工作。

任何解决方案?

1 个答案:

答案 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
    }
};