Java 防止/使其不受用户在设置中更改时间的影响

Java 防止/使其不受用户在设置中更改时间的影响,java,android-studio,time,Java,Android Studio,Time,我有一个闹钟应用程序,当它停止并激活时,闹钟仍会在设定的时间播放。当用户返回应用程序时,他/她可以看到闹钟上剩余的时间 我用来设置剩余报警时间的方法和变量是使用PendingEvent和alarm Manager以及System.currentTimeMillis() 一切都很好。例如,如果时间为: 上午10:00,我将闹钟设置为上午10:40,然后有一个倒计时计时器,在TextView的帮助下显示剩余时间,即40分钟,它向下计数,直到达到0。当达到0时,报警被调用 但是,如果用户转到智能手机中

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

我用来设置剩余报警时间的方法和变量是使用PendingEvent和alarm Manager以及System.currentTimeMillis()

一切都很好。例如,如果时间为: 上午10:00,我将闹钟设置为上午10:40,然后有一个倒计时计时器,在TextView的帮助下显示剩余时间,即40分钟,它向下计数,直到达到0。当达到0时,报警被调用

但是,如果用户转到智能手机中的“设置”应用程序,并在警报激活时将系统时间更改为上午9:00。然后,如果我返回报警应用程序,文本视图显示还有100分钟。从上午10:40到上午9:00=相差100分钟

我想阻止这种事情发生。是否有一种方法可以防止用户在警报激活时更改系统时间,或者是否有其他解决方案

我试图做的是检查系统是否正常;在onStart()中;小于savedprefs System.currentTimeMillis()的值;从顶部开始。如果低于此值,我希望立即调用警报

但是,为了让它工作,用户必须在更改系统时间后返回报警应用程序,如果用户不返回,则它将无法工作


有什么解决办法吗?

你不想告诉对方不要改变他的通话时间。这是他的选择,不是你的;)

此外,如果用户将闹钟设置为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();
 long timeLeftInMillis=initialTime;
 timer = new CountDownTimer(initialTime, 1000) {
       @Override
        public void onTick(long millisecondsUntilFinished) {
            timeleft = millisecondsUntilFinished;
        }
      }
这可能会像预期的那样起作用;)时间不依赖于第一次迭代后的系统时间

不过,你可能会面临另一个问题。为了解决这一问题,您需要将计时器作为一项服务启动,并在倒数计时结束时启动到
sendBroadcast()
,然后在主应用程序中创建一个
BroadcastReceiver
,以接收该广播并打开音乐(或您的闹钟所做的任何操作)。在onTick()事件中,您可以广播剩余时间,在应用程序中,您可以接收广播并获得剩余时间

您不想在onStart()中更新时间并进行更多计算。一旦你启动了计时器,并且它作为一项服务工作,让它处理时间计算,在你的主要活动中,只需担心剩余时间的显示(从计时器广播中获取),并在警报触发时做一些事情(也从计时器广播中获取)

如果不使用计时器作为服务,则计算剩余时间,如下所示:

long initialTimeLeft= calculateTheTimeFromSystemTime(); // you write that ;)
new CountDownTimer(initialTimeLeft, 1000) {

    public void onTick(long millisUntilFinished) {
        broadcastRemainingTime();
    }

    public void onFinish() {
        broadcastTimerHasFinished();
    }

}.start();
 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
    }
};

您可以从internet上的某些服务读取当前时间,这样就可以独立于所设置的设备时钟。如果你认为这可能会对你有所帮助,请使用你的搜索引擎获取详细信息。那么,如果用户离线,你不需要一直阅读时间:)你知道用户已打开闹钟40分钟。你只需要做一个40分钟的计时器,瞧,你就完成了。不需要每次都重新计算,因为如果我重新打开应用程序,会导致问题。因为savedprefs和onstart()的更新时间,这就是我的意思。您不希望每次启动时都更新时间。你运行计时器,让它处理时间。如果你想在重新打开应用程序时获得剩余时间,可以询问计时器。例如,通过在onTick()event中每秒广播剩余时间,我稍微更改了我的答案以使其更清晰。您不希望保留系统时间等。如果您使用系统时间,那么您将获得当前通过更改剩余时间获得的行为(正如我在回答中所说,这可能是正确的)