简体   繁体   English

重新打开应用程序时恢复计时器

[英]Resume timer when app is reopened

I am trying to find a way to start a count-up timer from a particular time (eg 01:34:22). 我正在尝试找到一种从特定时间开始启动递增计时器的方法(例如01:34:22)。 At the moment I have a button which can be tapped to start the timer, but I need the timer to 'continue' when the app is closed. 目前,我有一个可以点击以启动计时器的按钮,但是当应用程序关闭时,我需要计时器“继续”。

Therefore I need to find a way to save the start time of the timer, and then resume when the app is reopened using the start time and the current time. 因此,我需要找到一种方法来保存计时器的开始时间,然后使用开始时间和当前时间在重新打开应用程序时恢复。

This is the code for the timer: 这是计时器的代码:

public abstract class CountUpTimer {
private final long interval;
private long base;

public CountUpTimer(long interval) {
    this.interval = interval;
}

public void start() {
    base = SystemClock.elapsedRealtime();
    handler.sendMessage(handler.obtainMessage(MSG));
}

public void stop() {
    handler.removeMessages(MSG);
}

public void reset() {
    synchronized (this) {
        base = SystemClock.elapsedRealtime();
    }
}

abstract public void onTick(long elapsedTime);

private static final int MSG = 1;

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        synchronized (CountUpTimer.this) {
            long elapsedTime = SystemClock.elapsedRealtime() - base;
            onTick(elapsedTime);
            sendMessageDelayed(obtainMessage(MSG), interval);
        }
    }
};

} }

And this is the code I am using to setup the timer: 这是我用来设置计时器的代码:

    private void setupTimer() {
    timerTextView = (TextView) findViewById(R.id.timerTextView);
    timer = new CountUpTimer(1) {
        @Override
        public void onTick(long elapsedTime) {
            timerCount = elapsedTime;
            String finalTimer = String.format("%02d:%02d:%02d",
                    TimeUnit.MILLISECONDS.toHours(elapsedTime),
                    TimeUnit.MILLISECONDS.toMinutes(elapsedTime),
                    TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime))
            );

            timerTextView.setText(finalTimer);
        }
    };

    timer.stop();
}

That's called when the view is created. 创建视图时会调用该方法。

And this is the code for when the start button is tapped: 这是点击开始按钮时的代码:

    private void addTimerLister() {
    startTimerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            timer.start();

            DateTime startTime = DateTime.now();
            long startTimeMilliseconds = startTime.getMillis();

            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString("attractionTimerName", currentAttraction.name);
            editor.putLong("attractionTimerStart", startTimeMilliseconds);
            editor.putBoolean("attractionTimerRunning", true);
            editor.commit();

            animateFade();
        }
    });
}

As you can see, I've made a start to saving the start time, but I need a way to resume the timer when the app is reopened. 如您所见,我已经开始节省开始时间,但是当重新打开应用程序时,我需要一种恢复计时器的方法。 I can use JodaTime if necessary. 如有必要,我可以使用JodaTime。

Anyone have any suggestions? 有人有什么建议吗?

Use SharedPreferences to store the current time in onPause and retrieve this time in onResume . 使用SharedPreferences在onPause存储当前时间,并在onResume检索该时间。 Remove handler messages in onPause and post message in onResume when you have retrieved the time. 检索时间后,请在onPause删除处理程序消息,并在onResume发布消息。

Reset the timer in onPause and reinitialize it in onResume with the retrieved time. 在onPause中重置计时器,然后在onResume使用获取的时间重新初始化计时器。

timer = new CountUpTimer(retrievedTime) {
        @Override
        public void onTick(long elapsedTime) {
            timerCount = elapsedTime;
            String finalTimer = String.format("%02d:%02d:%02d",
                    TimeUnit.MILLISECONDS.toHours(elapsedTime),
                    TimeUnit.MILLISECONDS.toMinutes(elapsedTime),
                    TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime))
            );

            timerTextView.setText(finalTimer);
        }
    };

If you don't want to reinitialize the timer again, send a message to the handler instead. 如果您不想再次重新初始化计时器,请向处理程序发送一条消息。

   Bundle b = new Bundle();
   b.putLong(YourClass.COUNTER_TIME, retrievedTime); // YourClass.COUNTER_TIME is a public static string
   Message msg = getHandler().obtainMessage(); // Write getHandler() in CountUpTimer
   msg.setData(b);
   mHandler.sendMessage(msg);

and then retrieve it in handleMessage() 然后在handleMessage()检索它

@Override
    public void handleMessage(Message msg) {
        synchronized (CountUpTimer.this) {
            long retrievedTime = msg.getData().getLong(YourClass.COUNTER_TIME, 0)
        }
    }

If you want the timer to be running even after the app is closed or the system kills the app, use a service. 如果您希望计时器在关闭应用程序或系统终止应用程序后仍在运行,请使用服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM