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

时间:2017-01-30 11:46:30

标签: android

您好我最近制作了一个简单的秒表应用程序,它工作正常。但是,当我切换屏幕并将其重新打开时,计时器显示最后一个时间值。例如,如果计时器显示00:00:10,则转动屏幕(持续5秒)将其重新打开,它将显示相同的值并开始增加时间值。

有什么建议吗?

由于

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

}

4 个答案:

答案 0 :(得分:2)

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

只需查看您的代码,只要您的活动runningfalse,您就会将Pauses的值更改为Stops。 并查看Timer,它只会在runningtrue时增加值。

答案 1 :(得分:1)

应该在后台运行的服务中创建秒表。您的活动应该只读取并显示服务逻辑的时间。

现在你的秒表是活动生命周期线程的bindend,因此当你的活动/应用程序在后台时停止计时。

请参阅here正确的实施示例。

答案 2 :(得分:0)

尝试在清单中添加此权限

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

答案 3 :(得分:0)

为了确保时钟一致性(您的问题 - 显示自启动以来的实时)和时钟准确性(避免小的累积错误),您只需要测量从开始时间开始经过的时间:

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

然后在你的计时器测量差异:

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

由于您的活动可能被销毁并且会话数据被删除,您应该在SharedPreferences中保存和恢复您的开始时间。您不像其他人建议的那样需要服务。

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

您可能想要在onSaveInstanceState() Bundle中保存这些值 - 但如果您长时间不使用该应用程序,系统将会销毁这些值。 SharedPreferences持续允许您测量任何长时间。

显然,当您开始/停止秒表时,您需要刷新保存的startTime。你也可以保存布尔值,这将允许你保持startTime和endTime或timeElapsed;有很多方法可以实现这一点,但基本的想法是始终测量开始时间和现在(或停止时间)之间的时差。