2010-02-24 6 views
7

У меня есть одна служба работает в фоновом режиме. Всякий раз, когда он начинает хранить в памяти начальное время в миллисекундах:Android: хронометр как постоянный секундомер. Как установить время начала? Что такое хронометр «База»?

startingTime = new Date().getTime(); 

Я хочу, чтобы отобразить хронометр, который начинает отсчет при запуске службы и никогда не останавливается до тех пор, пока пользователь не нажмет кнопку. Я хочу разрешить пользователю оставлять активность, отображая хронометр, делать некоторые вещи, а затем возвращаться. Но идея состоит в том, что когда пользователь возвращается, я не хочу, чтобы хронометр снова возвращался в 0:00. Insted Я хочу, чтобы он показывал точное время, которое прошло с момента запуска службы.

я могу вычислить ElapsedTime каждый раз, когда пользователь вернуться к хронометра деятельности:

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

Дело в том, что я не знаю, как сказать, хронометр, чтобы начать отсчет с этого времени!

Установка его в качестве базы хронометра не работает. Может кто-нибудь объяснить, что именно означает «база» или как это сделать?

спасибо большое! BYE

ответ

20

Вы можете использовать Chronometer.

Вы также должны проверить this thread.

EDIT: Решение:

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

Да я уже видел, что и попробовал, но хронометр это всегда получают resseted ... Она начинается в 0:00 в любое время! Я даже не могу начать с постоянного значения, отличного от 0:00. – Santiago

+0

Отличный ответ чувак !!! Большое спасибо !!!! – Arun

+0

Спасибо Macarse .... я искал точное это ... Я потратил много часов на это .... спасибо buddy – shripal

4

Основание время это время, что Chronometer начал отсчитывают в. Вы можете установить его с помощью Chronometer.setBase(). Вы должны получить базовое время, используя SystemClock.getElapsedTime(). Вызовите setBase() с временем начала при каждом запуске Chronometer. Если есть потенциал для уничтожения и воссоздания Activity, когда таймер по-прежнему активен, вам нужно будет удерживать базовое время где-то вне Activity, которому принадлежит Chronometer.

1

Какое-то странное с SystemClock.getElapsedTime(), я сделал некоторые изменения для нормальной, используя с даты начала, как

myChron.setBase(startDate.getTime()); 

Здесь ребенок хронометр ниже, 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); 
     } 
    } 
} 

Просто скопировать и использовать , он работает для меня

+0

Не могли бы вы объяснить, что вы изменили в реализации класса хронометра фреймворка? – faizal

+0

http://stackoverflow.com/a/19774399/2590478 – MidasLefko

2

Чтобы начать хронометр, вы должны использовать метод вашего хронометра setBase() с SystemClock.elapsedRealTime(). Так же, как это:

mChronometer.setBase(SystemClock.elapsedRealTime()) 

Но если вы хотите, чтобы начать в другое время, вы должны вычесть время, которое вы хотите в миллисекундах.Например, вы хотите начать свой хронометр на 10 секунд:

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

На 2 минуты:

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

Но проблема здесь заключается в том, что хронометр покажет «00:00» время до того, как начать рассчитывать, чтобы изменить его в свое время вы должны сделать:

mChronometer.setText("02:00"); 
0

Это работает для меня:

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(); 
1

Когда вы устанавливаете базовое время с .setBase (SystemClock.elapsedRealTime()), хронометр начинает отсчет с 00.00, но время, которое он хранит, - это количество milisecs от загрузки. Когда вы используете .stop, внутренний счетчик не останавливается, просто время, которое вы видите на часах. Итак, если вы снова используете .start, счетчик часов переходит к реальному счету. Если вы хотите сохранить время, прошедшее с момента запуска, вам нужно снова получить время, прошедшее через Систему, и внести изменения в .setTime

+0

любое предложение, как мы можем это реализовать? SystemClock.elapsedRealtime() - mElapsedTime; не работает – AndroidGuy

1

Как установить время начала? Что такое хронометр «База»?

Использование SystemClock.elapsedRealtime() для этой цели:

myChronometer.setBase(SystemClock.elapsedRealtime());