简体   繁体   English

屏幕关闭时,android秒表停止工作

[英]android stopwatch stops working when screen is off

Hi I recently have made a simple stopwatch app, it work fine. 嗨,我最近做了一个简单的秒表应用程序,它工作正常。 However when I switch the screen of and turn it back on the timer shows the last value of time. 但是,当我切换屏幕并将其重新打开时,计时器显示最后一个时间值。 For example if the timer was showing me 00:00:10 , turn the screen of (for 5s) turn it back on it and it will show same value and the starts to increase the time value. 例如,如果计时器显示00:00:10,则转动屏幕(持续5秒)将其重新打开,它将显示相同的值并开始增加时间值。

Any suggestion why ? 有什么建议吗?

Thanks 谢谢

      if (savedInstanceState != null) {
        seconds = savedInstanceState.getInt("seconds");
        running = savedInstanceState.getBoolean("running");
        wasRunning = savedInstanceState.getBoolean("wasRunning");
    }

    runTimer();
}


public void onClickStart(View view){
    running = true;
}

public void onClickStop(View view){
    running = false;
}

public void onClickReset(View view){
    running = false;
    seconds = 0;
}


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putInt("seconds", seconds);
    savedInstanceState.putBoolean("running", running);
    savedInstanceState.putBoolean("wasRunning",wasRunning);
}


@Override
protected void onPause(){
    super.onPause();
    wasRunning = running;
    running = false;
}

@Override
protected void onResume(){
    super.onResume();
    if(wasRunning){
        running = true;
    }
}

@Override
protected void onStop(){
    super.onStop();
    wasRunning = running;
    running = false;
}

@Override
protected void onStart(){
    super.onStart();
    if(wasRunning){
        running = true;
    }
}

private void runTimer(){
    final TextView timeView = (TextView)findViewById(R.id.time_view);
    final Handler handler = new Handler();

    handler.post(new Runnable() {
        @Override
        public void run() {

            int hours = seconds/3600;
            int minutes = (seconds%3600)/60;
            int secs = seconds%60;

            String time = String.format("%d:%02d:%02d",hours,minutes,secs);
            timeView.setText(time);

            if(running){
                seconds++;
            }
            handler.postDelayed(this,1000);
        }
    });

}
@Override
protected void onPause(){
    super.onPause();
    wasRunning = running;
    running = false;
}

@Override
protected void onResume(){
    super.onResume();
    if(wasRunning){
        running = true;
    }
}

@Override
protected void onStop(){
    super.onStop();
    wasRunning = running;
    running = false;
}

@Override
protected void onStart(){
    super.onStart();
    if(wasRunning){
        running = true;
    }
}

Just look into your code, you are changing the value of running to false whenever your activity Pauses or Stops . 只需查看代码,只要您的活动PausesStops您就会将running的值更改为false And look into the Timer, it only increases the value if running is true . 并查看Timer,如果runningtrue ,它只会增加值。

The stopwatch should be created within a service that runs in the background. 秒表应该在后台运行的服务中创建。 Your activity should only read and present the time out of the service logic. 您的活动应该只读取并显示服务逻辑的时间。

Right now your stopwatch is bindend to the activity lifecycle thread and because of it the time count is stopped while your activity / app is in the background. 现在你的秒表是活动生命周期线程的bindend,因此当你的活动/应用程序在后台时,时间计数就会停止。

See here a right implementation example. 请参见此处的正确实施示例。

尝试在清单中添加此权限

<uses-permission android:name="android.permission.WAKE_LOCK" />

To ensure both clock consistency (your problem - show the real time since start) and clock accuracy (avoid small cumulative errors) you just have to measure the time elapsed from your start time: 为确保时钟一致性(您的问题 - 显示自启动以来的实时)和时钟准确性(避免小的累积错误),您只需测量从开始时间开始经过的时间:

// first get the time in miliseconds
long start = System.currentTimeMillis();

Then in your timer measure the difference: 然后在你的计时器测量差异:

// every now and then, get the current time and substract
long now = System.currentTimeMillis();
seconds = (now - start) / 1000;

As your activity could be destroyed and session data dropped, you should save and restore your start time in SharedPreferences. 由于您的活动可能被销毁并且会话数据被删除,您应该在SharedPreferences中保存和恢复您的开始时间。 You do not need a Service as others suggested. 您不像其他人建议的那样需要服务。

@Override
protected void onCreate(Bundle state){
   super.onCreate(state);
   . . .

   // Restore preferences
   SharedPreferences settings = getSharedPreferences();
   start = settings.getLong("start_time", 0);
   if (start != 0) {
       running = true;
   }
}

 @Override
 protected void onStop(){
 super.onStop();
 if (running) {
     SharedPreferences settings = getSharedPreferences();
     SharedPreferences.Editor editor = settings.edit();
     editor.putLong("start_time", startTime);
     editor.apply();
 }

You could be tempted to save these values in onSaveInstanceState() Bundle - but this will be destroyed by the System if you don't use the app for a long time. 您可能想要将这些值保存在onSaveInstanceState() Bundle中 - 但如果您长时间不使用该应用程序,系统将会销毁这些值。 The SharedPreferences are persistent allowing you to measure any long period of time. SharedPreferences是持久的,允许您测量任何长时间。

Obviously you need to refresh the saved startTime when you start / stop the stop watch. 显然,当您启动/停止秒表时,您需要刷新保存的startTime。 You can also save the boolean and this would allow you to keep the startTime and endTime or timeElapsed; 你也可以保存布尔值,这将允许你保持startTime和endTime或timeElapsed; there are many ways you can implement this but the basic ideea is always measure the time difference between start time and now (or stop time). 有很多方法可以实现这个,但基本的ideea 总是测量开始时间和现在 (或停止时间) 之间的时间差

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

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