午夜后的倒数计时器错误(与时区和时钟有关)

时间:2019-01-01 21:34:15

标签: java android github timer open-source

我的应用程序中有几个用户报告了一个奇怪的时间重置/错误行为,我对此感到困惑,并且在测试和收集日志之后-我发现我的计时器(如果在午夜之前启动)会重置为立即超过20个小时,我不知道为什么或如何防止这种情况。

该项目是开源的,欢迎任何人帮助我,这是链接:

GitHub

有关应用程序/项目的信息:

  • 选择应用,选择所需的锁定时间,然后锁定应用。

My Timer Class ( Full )

与时间/日期相关的摘要

 public class Timer_Service extends Service {

public static final long NOTIFY_INTERVAL = 1000;
public static String str_receiver = "com.nephi.getoffyourphone.receiver";
public String str_testing;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
//Root Detector
RootBeer rootbeer;
//Con Manager
WifiManager wifiManager;
//DH Helper
DB_Helper db;
Intent intent;
Intent lockIntent;
Intent Shame;
//Shame Int Counter
private Handler mHandler = new Handler();
private Timer mTimer = null;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    //Lock Screen launch
    lockIntent = new Intent(this, locked.class);
    lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    calendar = Calendar.getInstance();
    simpleDateFormat = new SimpleDateFormat("H:M:ss");

    mTimer = new Timer();
    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
    intent = new Intent(str_receiver);

    //Root Detector
    rootbeer = new RootBeer(this);
    //Wifi Manager
    wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

    //DB
    db = new DB_Helper(this);
}  

public String twoDatesBetweenTime() {


    try {
        date_current = simpleDateFormat.parse(strDate);
    } catch (Exception e) {

    }

    try {
        // Gets the first timestamp when the lockdown started
        date_diff = simpleDateFormat.parse(db.get_Data(1));
    } catch (Exception e) {

    }

    try {


        long diff = date_current.getTime() - date_diff.getTime();
        int int_hours = Integer.valueOf(db.get_Hours(1));
        long int_timer;
        if (int_hours > 10) {
            int_timer = TimeUnit.MINUTES.toMillis(int_hours);
        } else {
            int_timer = TimeUnit.HOURS.toMillis(int_hours);
        }
        long long_hours = int_timer - diff;
        long diffSeconds2 = long_hours / 1000 % 60;
        long diffMinutes2 = long_hours / (60 * 1000) % 60;
        long diffHours2 = long_hours / (60 * 60 * 1000) % 24;


        if (long_hours >= 0) {
            str_testing = String.format("%d:%d:%02d", diffHours2, diffMinutes2, diffSeconds2);
            Log.e("TIME", str_testing);

        } else {
            stopService(new Intent(getApplicationContext(), Timer_Service.class));

            mTimer.cancel();
        }

有什么建议吗?


编辑:

  • 计时器工作正常,如果有人设置锁定时间(例如30分钟),它将倒计时30分钟并在完成后解锁。

假设有人在21:30:00开始锁定,计时器将正常工作并在10:00:00结束。

但是,如果有人在23:55:00开始锁定30分钟,那么“解锁的剩余时间”将跳到21小时,而不是30分钟。这仅在新的一天开始/计时器在午夜之前开始时发生。

1 个答案:

答案 0 :(得分:0)

出现问题是因为您将时间存储为“ H:m:ss”格式,但是您忽略了日期方面。使用System.currentTimeMillis()为您提供1970年1月1日之后的毫秒数。因此,这包括日期方面。取两个值的差将为您提供过期的毫秒数,您可以针对任何时间间隔检查经过的时间。


改为:

在保存计时器时间时,应开始使用毫秒而不是H:mm:ss:

long millisNow = System.currentTimeMillis();

将millis保存到数据库。

并保存应该经过的时间:

int minutes = 30;
long millisElapse = 30 * 60 * 1000;

将其保存到数据库(或您需要的时间间隔)

立即有所不同

long diff = timeNow - timeDatabase;

if(diff > millisElapse){
    //end session
}


顺便说一句:您发布“ H:M:ss”的格式。大写字母“ M”代表月份(!),而不是分钟。
看一下“日期和时间模式” SimpleDateFormat

上的文档