我有一个闹钟应用程序,当它停止并激活时,闹钟仍会在设定的时间播放。当用户返回应用程序时,他/她可以看到闹钟剩余的时间。
我用来设置警报剩余时间的方法和变量是使用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/