Android - 即使在关闭应用时计算背景时间

Android - 即使在关闭应用时计算背景时间

问题描述:

我有一个textview它的行为stepuptimer。我使用了一个处理程序,并且每秒更新它,并且它的工作完美。但是,当我关闭应用程序并打开时,计时器从“0”开始。我想要时间来运行背景,当我打开活动时,应该显示经过的时间,而不是从0开始。显示时间格式为00:00:00Android - 即使在关闭应用时计算背景时间

我的代码是

public class GoOnlinePage extends Activity { 

private TextView Tv_timer; 
private Handler onlineTimeHandler = new Handler(); 
private long startTime = 0L; 
private long timeInMilliseconds = 0L; 
private long timeSwapBuff = 0L; 
private long updatedTime = 0L; 
private int mins; 
private int secs; 
private int hours; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.go_online_page); 

    Tv_timer = (TextView) findViewById(R.id.txt_timer); 

    startTime = SystemClock.uptimeMillis(); 

    onlineTimeHandler.post(updateTimerThread); 


    } 



    private Runnable updateTimerThread = new Runnable() { 

    public void run() { 

     timeInMilliseconds = SystemClock.uptimeMillis() - startTime; 

     updatedTime = timeSwapBuff + timeInMilliseconds; 

     secs = (int) (updatedTime/1000); 
     hours = secs/(60 * 60); 
     mins = secs/60; 
     secs = secs % 60; 
     if (mins >= 60) { 
      mins = 0; 
     } 


     Tv_timer.setText(String.format("%02d", hours) + ":" + 
     String.format("%02d", mins) + ":" 
       + String.format("%02d", secs)); 



     onlineTimeHandler.postDelayed(this, 1 * 1000); 

    } 

}; 

} 

我尝试使用会话和更新的时间每一秒内updateTimerThread。当我打开应用程序时,我得到当前时间并找到两次之间的差异并更新计时器。但没有任何工作。

请帮帮我。提前致谢。

编辑

解决

我解决它通过使用服务,并通过使用的BroadcastReceiver更新TextView的。我已附上以下代码供您参考。

import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.SystemClock; 
import android.util.Log; 



public class TimerService extends Service { 
    private static String LOG_TAG = "TimerService"; 
    private IBinder mBinder = new MyBinder(); 

    Handler onlineTimeHandler = new Handler(); 
    long startTime = 0L, timeInMilliseconds = 0L, timeSwapBuff = 0L, updatedTime = 0L; 
    int mins, secs, hours; 
    String time = ""; 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.v(LOG_TAG, "in onCreate"); 
     startTime = SystemClock.uptimeMillis(); 
     onlineTimeHandler.post(updateTimerThread); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     Log.v(LOG_TAG, "in onBind"); 
     return mBinder; 
    } 

    @Override 
    public void onRebind(Intent intent) { 
     Log.v(LOG_TAG, "in onRebind"); 
     super.onRebind(intent); 
    } 

    @Override 
    public boolean onUnbind(Intent intent) { 
     Log.v(LOG_TAG, "in onUnbind"); 
     return true; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.v(LOG_TAG, "in onDestroy"); 
     if(onlineTimeHandler!=null){ 
      onlineTimeHandler.removeCallbacks(updateTimerThread); 
     } 
    } 


    public class MyBinder extends Binder { 
     TimerService getService() { 
      return TimerService.this; 
     } 
    } 

    private Runnable updateTimerThread = new Runnable() { 

     public void run() { 

      timeInMilliseconds = SystemClock.uptimeMillis() - startTime; 

      updatedTime = timeSwapBuff + timeInMilliseconds; 

      secs = (int) (updatedTime/1000); 
      hours = secs/(60 * 60); 
      mins = secs/60; 
      secs = secs % 60; 
      if (mins >= 60) { 
       mins = 0; 
      } 

      time = String.format("%02d", hours) + ":" + String.format("%02d", mins) + ":" 
        + String.format("%02d", secs); 


      Intent intent = new Intent(); 
      intent.setAction("com.app.Timer.UpdateTime"); 
      intent.putExtra("time", time); 
      sendBroadcast(intent); 

      onlineTimeHandler.postDelayed(this, 1 * 1000); 

     } 

    }; 
} 
+0

这可能会帮助你:https://*.com/questions/13401205/android-timer-that-c​​ounts-when-app-is-closed –

+0

为什么你不保存上次更新的时间在[SharedPreferences ](https://developer.android.com/reference/android/content/SharedPreferences.html)什么的? – shadygoneinsane

+0

@shadygoneinsane - 我试着将它保存在共享首选项中并获取它。但它只保存应用程序打开时的最后一次。即使应用程序关闭,我也需要计时器。 –

当您的活动被破坏Tv_timer对象也将被破坏,一个哪个线程是updating.When活动再次启动创建Tv_timer的新对象。

同样的时间可以存储在某个地方,当应用程序启动

后来用

有可能实现这一目标有两种方式:

  1. 可以使用Service定时器,它会保持甚至跑步如果应用程序在后台或被杀害。
  2. 使用SharedPreference和存储计时器值的app被杀害,当,当应用程序重新启动,就取这个值,当你的计时器在一些持久的地方开始与持续时间

商店startTime值和它(如SharedPreferences等等),并删除当你的计时器结束。

在您的Activity#onCreate方法中,检查持久值,如果存在,请使用该值初始化您的值startTime而不是当前系统时间。

的问题关系到你的代码的一些技巧:

  • 使用new Date().getTime()而不是SystemClock.uptimeMillis()。它使您的代码在重新启动时更加健壮。
  • 当您拨打Activity#onPause时,停止您的计时器代码,并在Activity#onResume调用时启动。由于您不需要在不可见的情况下更新您的用户界面,因此无需进行更新。

很简单,使用一些静态变量。 这个例子继续,即使该活动是在后台或毁坏计数,没有SharedPreferences或服务需要

public class MainActivity extends AppCompatActivity { 

    private static TextView txtCounter; 
    private static Handler handler; 
    private static Runnable runnable ; 
    private static int count; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     txtCounter = (TextView) findViewById(R.id.txtCounter); 
     if (handler == null) { 
      handler = new Handler(); 
      runnable = new Runnable() { 
       @Override 
       public void run() { 
        txtCounter.setText("Count = " + count); 
        count++; 
        handler.postDelayed(runnable, 1000); 
       } 
      }; 
      handler.postDelayed(runnable, 1000); 
     } 
    } 

} 

UPDATE:

要暂停:handler.removeCallbacks(runnable);

要恢复: handler.postDelayed(runnable, 1000);

重置计数器:count = 0;

+0

你如何开始/停止/暂停计数器? – Hansie

+0

看看更新的答案。 –