Android: cronómetro como un cronómetro persistente. ¿Cómo establecer la hora de inicio? ¿Qué es el cronómetro "Base"?

Tengo un servicio que funciona en el fondo. Cada vez que se inicia, almacenar en memoria el tiempo de inicio en milisegundos:

startingTime = new Date().getTime(); 

Quiero mostrar un cronómetro que comienza a contar cuando el servicio se inicia y nunca se detiene hasta que el usuario presiona un botón. Quiero permitir que el usuario deje la actividad de hacer el cronómetro, hacer algunas cosas y luego volver. Pero la idea es que cuando el usuario regrese no quiero que el cronómetro vuelva a 0:00. Insted Quiero que muestre el tiempo exacto que ha pasado desde que el servicio ha comenzado.

Puedo calcular el tiempo transcurrido cada vez que el usuario vuelve a la actividad del cronómetro:

 elapsedTime = new Date().getTime() - startingTime; 

La cosa es que no sé cómo decir el cronómetro para empezar a contar desde ese momento!

La configuración como base del cronómetro no funciona. ¿Puede alguien explicar qué significa exactamente "base" o cómo lograrlo?

¡muchas gracias! ADIÓS

Usted puede utilizar el cronómetro .

También debe comprobar este hilo .

EDIT: La solución:

 public class ChronoExample extends Activity { Chronometer mChronometer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); mChronometer = new Chronometer(this); // Set the initial value mChronometer.setText("00:10"); layout.addView(mChronometer); Button startButton = new Button(this); startButton.setText("Start"); startButton.setOnClickListener(mStartListener); layout.addView(startButton); Button stopButton = new Button(this); stopButton.setText("Stop"); stopButton.setOnClickListener(mStopListener); layout.addView(stopButton); Button resetButton = new Button(this); resetButton.setText("Reset"); resetButton.setOnClickListener(mResetListener); layout.addView(resetButton); setContentView(layout); } private void showElapsedTime() { long elapsedMillis = SystemClock.elapsedRealtime() - mChronometer.getBase(); Toast.makeText(ChronoExample.this, "Elapsed milliseconds: " + elapsedMillis, Toast.LENGTH_SHORT).show(); } View.OnClickListener mStartListener = new OnClickListener() { public void onClick(View v) { int stoppedMilliseconds = 0; String chronoText = mChronometer.getText().toString(); String array[] = chronoText.split(":"); if (array.length == 2) { stoppedMilliseconds = Integer.parseInt(array[0]) * 60 * 1000 + Integer.parseInt(array[1]) * 1000; } else if (array.length == 3) { stoppedMilliseconds = Integer.parseInt(array[0]) * 60 * 60 * 1000 + Integer.parseInt(array[1]) * 60 * 1000 + Integer.parseInt(array[2]) * 1000; } mChronometer.setBase(SystemClock.elapsedRealtime() - stoppedMilliseconds); mChronometer.start(); } }; View.OnClickListener mStopListener = new OnClickListener() { public void onClick(View v) { mChronometer.stop(); showElapsedTime(); } }; View.OnClickListener mResetListener = new OnClickListener() { public void onClick(View v) { mChronometer.setBase(SystemClock.elapsedRealtime()); showElapsedTime(); } }; } 

El tiempo de base es el tiempo que el Chronometer empezó a marcar. Puede configurarlo usando Chronometer.setBase() . Debe obtener el tiempo base utilizando SystemClock.getElapsedTime() . Llamar a setBase() con la hora de inicio cada vez que se inicia el Chronometer . Si hay potencial para que la Activity sea ​​destruida y recreada mientras el temporizador está todavía activo, entonces necesitará mantener el tiempo base en algún lugar fuera de la Activity que posee el Chronometer .

Para iniciar el cronómetro debe utilizar el método setBase() de su cronómetro con SystemClock.elapsedRealTime() . Justo como esto:

 mChronometer.setBase(SystemClock.elapsedRealTime()) 

Pero si quieres empezar en otro momento, tienes que restar el tiempo que quieres en milisegundos. Por ejemplo, desea iniciar su cronómetro en 10 segundos:

 mChronometer.setBase(SystemClock.elapsedRealTime() - 10*1000); 

A los 2 minutos:

 mChronometer.setBase(SystemClock.elapsedRealTime() - 2*60*1000); 

Pero el problema aquí es que el Cronómetro mostrará "00:00" el tiempo antes de que comience a contar, para cambiarlo a su tiempo usted tiene que hacer eso:

 mChronometer.setText("02:00"); 

Algunos extraño con SystemClock.getElapsedTime (), hice algunos cambios para el uso normal con fecha de inicio, como

 myChron.setBase(startDate.getTime()); 

Aquí el niño de Chronometer abajo, TimeView

 import android.R; import android.content.Context; import android.content.res.TypedArray; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.Log; import android.widget.Chronometer; import android.widget.RemoteViews; import java.util.Formatter; import java.util.IllegalFormatException; import java.util.Locale; @RemoteViews.RemoteView public class TimeView extends Chronometer { private static final String TAG = "TimeView"; private long mBase; private boolean mVisible; private boolean mStarted; private boolean mRunning; private boolean mLogged; private String mFormat; private Formatter mFormatter; private Locale mFormatterLocale; private Object[] mFormatterArgs = new Object[1]; private StringBuilder mFormatBuilder; private OnChronometerTickListener mOnChronometerTickListener; private StringBuilder mRecycle = new StringBuilder(8); private static final int TICK_WHAT = 2; /** * Initialize this Chronometer object. * Sets the base to the current time. */ public TimeView(Context context) { this(context, null, 0); } /** * Initialize with standard view layout information. * Sets the base to the current time. */ public TimeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } /** * Initialize with standard view layout information and style. * Sets the base to the current time. */ public TimeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mBase = System.currentTimeMillis(); updateText(mBase); } public void setBase(long base) { mBase = base; dispatchChronometerTick(); updateText(System.currentTimeMillis()); } /** * Return the base time as set through {@link #setBase}. */ public long getBase() { return mBase; } public void start() { mStarted = true; updateRunning(); } /** * Stop counting up. This does not affect the base as set from {@link #setBase}, just * the view display. * <p/> * This stops the messages to the handler, effectively releasing resources that would * be held as the chronometer is running, via {@link #start}. */ public void stop() { mStarted = false; updateRunning(); } /** * The same as calling {@link #start} or {@link #stop}. * * @hide pending API council approval */ public void setStarted(boolean started) { mStarted = started; updateRunning(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mVisible = false; updateRunning(); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); mVisible = visibility == VISIBLE; updateRunning(); } private synchronized void updateText(long now) { long seconds = now - mBase; seconds /= 1000; String text = DateUtils.formatElapsedTime(mRecycle, seconds); if (mFormat != null) { Locale loc = Locale.getDefault(); if (mFormatter == null || !loc.equals(mFormatterLocale)) { mFormatterLocale = loc; mFormatter = new Formatter(mFormatBuilder, loc); } mFormatBuilder.setLength(0); mFormatterArgs[0] = text; try { mFormatter.format(mFormat, mFormatterArgs); text = mFormatBuilder.toString(); } catch (IllegalFormatException ex) { if (!mLogged) { Log.w(TAG, "Illegal format string: " + mFormat); mLogged = true; } } } setText(text); } private void updateRunning() { boolean running = mVisible && mStarted; if (running != mRunning) { if (running) { updateText(System.currentTimeMillis()); dispatchChronometerTick(); mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), 1000); } else { mHandler.removeMessages(TICK_WHAT); } mRunning = running; } } private Handler mHandler = new Handler() { public void handleMessage(Message m) { if (mRunning) { updateText(System.currentTimeMillis()); dispatchChronometerTick(); sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000); } } }; void dispatchChronometerTick() { if (mOnChronometerTickListener != null) { mOnChronometerTickListener.onChronometerTick(this); } } } 

Sólo copiar y usar, funciona para mí

Cuando se establece el tiempo base con .setBase (SystemClock.elapsedRealTime ()) el chronomether comienza a contar desde 00.00 pero el tiempo que almacena es la cantidad de milisecs desde el arranque. Cuando se utiliza .stop el conteo interno no se detiene, sólo el tiempo que ve en el reloj. Por lo tanto, si utiliza .start nuevamente, la cuenta de reloj salta a la cuenta real. Si desea almacenar el tiempo transcurrido desde el inicio, tiene que volver a obtener el tiempo transcurrido del sistema y marcar la diferencia con .setTime

Esto funciona para mí:

 Date now = new Date(); long elapsedTime = now.getTime() - startTime.getTime(); //startTime is whatever time you want to start the chronometer from. you might have stored it somwehere myChronometer.setBase(SystemClock.elapsedRealtime() - elapsedTime); myChronometer.start(); 

¿Cómo establecer la hora de inicio? ¿Qué es el cronómetro "Base"?

Utilice SystemClock.elapsedRealtime() para este propósito:

  myChronometer.setBase(SystemClock.elapsedRealtime()); 
  • Tarea regular de Android (equivalente a cronjob)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.