java - 防止/使其未经授权用户更改“设置”中的时间

标签 java android-studio time

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

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

一切都运行得很好。如果时间是例如: 上午 10:00,我设置闹钟在上午 10:40 响起,然后有一个倒计时器,借助 TextView 显示剩余时间,即 40 分钟,并向下倒数直到达到 0。达到 0 时将发出警报。

但是,如果用户进入智能手机中的设置应用程序并将系统时间更改为上午 9:00,同时闹钟处于 Activity 状态。然后,如果我返回闹钟应用程序,Textview 将显示还剩 100 分钟。自上午 10:40 至上午 9:00 = 100 分钟差异。

我想阻止这种情况发生。有没有办法阻止用户在闹钟处于 Activity 状态时更改系统时间,或者是否有其他解决方案?

我试图做的是检查 System.currentTimeMillis(); 是否在 onStart() 中;小于保存的首选项 System.currentTimeMillis();从 onStop.如果小于,那么我希望立即调用警报。

但是要使其工作,用户必须在更改系统时间后返回闹钟应用程序,如果用户不返回,则它将无法工作。

有什么解决办法吗?

最佳答案

好吧,您不想告诉这个人不要更改他的手机时间。这是他的选择,不是你的;)

此外,如果用户将闹钟设置为 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() 中的时间并进行更多计算。一旦您启动了计时器并且它作为服务工作,让它处理时间计算,并且在您的主要 Activity 中只需担心剩余时间的显示(从计时器广播中获取)并在警报触发时执行某些操作(也可以获取来自定时器广播)

如果您不使用计时器作为服务,那么您可以这样计算剩余时间:

 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);
            }

在主要 Activity 中:

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

关于java - 防止/使其未经授权用户更改“设置”中的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50057532/

相关文章:

java - 如何将版本变量从build.gradle文件获取到java spring boot Controller 中?

Java - 函数没有返回我所期望的

java - 运行时异常 : Unable to instantiate activity

android - 下载谷歌 API 英特尔 x86 atom 系统镜像时出错

c++ - gmtime 返回不正确的时间

c - 按时间播种的随机数不会改变

java - Jacoco exec 文件总是出现 EOFException

android - 在 Google Play 下载我的应用程序时包文件无效

android - Gradle 同步失败 : invalid type code: 6C

python - 从时间中提取小时部分并使用 pandas 将其作为整数返回