# Class WorkoutSession

java.lang.Object
com.codename1.health.workout.WorkoutSession

public abstract class WorkoutSession extends Object

A workout being recorded.

Obtained from `WorkoutManager.startSession(WorkoutConfiguration)`. The state machine, the elapsed clock and the rollup of fed samples live here in shared code; ports implement only the `do*` methods.

##### Live and recorded sessions

`isLive()` tells you whether the operating system is running a real workout session -- keeping the app alive and collecting sensor data itself. That is the case on watchOS, on iOS 26 and later, and on Wear OS.

On an Android phone it is not, because Health Connect has no such concept: Google's documented approach there is to record the session yourself and write it when it ends, which is exactly what a recorded session does. So a recorded session is not a degraded shim -- it is the platform-correct design -- but it does mean nothing is collected unless you feed it, through `addSamples(List)` or by attaching a Bluetooth sensor with `SensorSessionOptions.setWorkoutSession(WorkoutSession)`.

Check `WorkoutManager.isSensorCollectionSupported()` before building UI that assumes a heart rate will appear on its own.

##### A killed workout is over

Sessions are deliberately not restored after the process dies. `end()` was never called, so nothing is written. An app that needs crash-resilient workouts should write partial records as it goes -- which is what the recorded path does anyway.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `WorkoutSession(WorkoutConfiguration configuration)`
  Ports and the framework construct sessions.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final AsyncResource<Boolean>`
  `addEvent(WorkoutEvent event)`
  Records an event -- a lap, a marker, a segment boundary.
  `final void`
  `addListener(WorkoutSessionListener listener)`
  Registers a listener for state, statistics and events.
  `final AsyncResource<Boolean>`
  `addSamples(List<HealthSample> samples)`
  Feeds samples into the workout.
  `final void`
  `discard()`
  Abandons the workout without writing anything.
  `protected void`
  `doAddSamples(List<HealthSample> samples, AsyncResource<Boolean> out)`
  Hands fed samples to the platform.
  `protected abstract void`
  `doDiscard()`
  Abandons the workout without persisting.
  `protected abstract void`
  `doEnd(AsyncResource<WorkoutSample> out)`
  Stops collection and persists the workout.
  `protected abstract void`
  `doPause(AsyncResource<Boolean> out)`
  Pauses platform collection.
  `protected void`
  `doPrepare(AsyncResource<Boolean> out)`
  Warms up sensors.
  `protected abstract void`
  `doResume(AsyncResource<Boolean> out)`
  Resumes platform collection.
  `protected abstract void`
  `doStart(AsyncResource<Boolean> out)`
  Starts platform collection.
  `final AsyncResource<WorkoutSample>`
  `end()`
  Ends the workout and writes it to the health store, resolving with the persisted record.
  `protected final void`
  `fireEvent(WorkoutEvent event)`
  Notifies listeners of an event.
  `protected final void`
  `fireFailed(HealthException error)`
  Reports an unrecoverable failure and moves to `WorkoutSessionState.FAILED`.
  `protected final void`
  `fireStatisticsUpdated(HealthDataType type)`
  Notifies listeners that a statistic changed.
  `final WorkoutConfiguration`
  `getConfiguration()`
  The configuration this session was started with.
  `final long`
  `getElapsedMillis()`
  Time spent recording, excluding pauses.
  `final long`
  `getEndedAtMillis()`
  When it ended, epoch millis, or 0 while still running.
  `final List<WorkoutEvent>`
  `getEvents()`
  Every event recorded so far.
  `final long`
  `getStartedAtMillis()`
  When the workout started, epoch millis, or 0 before `start()`.
  `final WorkoutSessionState`
  `getState()`
  The current state.
  `final HealthQuantity`
  `getStatistic(HealthDataType type, AggregateMetric metric)`
  A live statistic, or `null` when the platform does not compute it and nothing has been fed in.
  `protected final Map<String, HealthQuantity>`
  `getStatisticsSnapshot()`
  The accumulated statistics, for ports assembling the final record.
  `boolean`
  `isLive()`
  Whether the operating system is running a real workout session -- see the class documentation.
  `final AsyncResource<Boolean>`
  `pause()`
  Pauses recording.
  `final AsyncResource<Boolean>`
  `prepare()`
  Warms up sensors ahead of `start()`, for apps that show a countdown.
  `final void`
  `removeListener(WorkoutSessionListener listener)`
  Removes a listener.
  `final AsyncResource<Boolean>`
  `resume()`
  Resumes after a pause.
  `protected final void`
  `setState(WorkoutSessionState newState)`
  Moves to a new state and notifies listeners.
  `final AsyncResource<Boolean>`
  `start()`
  Starts recording.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### WorkoutSession

    protected WorkoutSession(WorkoutConfiguration configuration)
    Ports and the framework construct sessions.

- ## Method Details

  - ### getConfiguration

    public final WorkoutConfiguration getConfiguration()
    The configuration this session was started with.

  - ### getState

    public final WorkoutSessionState getState()
    The current state.

  - ### isLive

    public boolean isLive()
    Whether the operating system is running a real workout session -- see the class documentation. `false` means the clock and the saved record are real but collection is entirely up to you.

  - ### prepare

    public final AsyncResource<Boolean> prepare()
    Warms up sensors ahead of `start()`, for apps that show a countdown. Optional; `start()` works without it.

  - ### start

    public final AsyncResource<Boolean> start()
    Starts recording.

  - ### pause

    public final AsyncResource<Boolean> pause()
    Pauses recording. The elapsed clock stops.

  - ### resume

    public final AsyncResource<Boolean> resume()
    Resumes after a pause.

  - ### end

    public final AsyncResource<WorkoutSample> end()
    Ends the workout and writes it to the health store, resolving with the persisted record.

  - ### discard

    public final void discard()
    Abandons the workout without writing anything.

  - ### getElapsedMillis

    public final long getElapsedMillis()
    Time spent recording, excluding pauses.

  - ### getStartedAtMillis

    public final long getStartedAtMillis()
    When the workout started, epoch millis, or 0 before `start()`.

  - ### getEndedAtMillis

    public final long getEndedAtMillis()
    When it ended, epoch millis, or 0 while still running.

  - ### getStatistic

    public final HealthQuantity getStatistic(HealthDataType type, AggregateMetric metric)

    A live statistic, or `null` when the platform does not compute it and nothing has been fed in.

    Never fabricates a zero. On a recorded session with no sensor attached every statistic is null, and showing "0 bpm" instead would be a claim the app cannot support.

  - ### addSamples

    public final AsyncResource<Boolean> addSamples(List<HealthSample> samples)
    Feeds samples into the workout. On a recorded session this is the only way anything is collected.

  - ### addEvent

    public final AsyncResource<Boolean> addEvent(WorkoutEvent event)
    Records an event -- a lap, a marker, a segment boundary.

  - ### getEvents

    public final List<WorkoutEvent> getEvents()
    Every event recorded so far.

  - ### addListener

    public final void addListener(WorkoutSessionListener listener)
    Registers a listener for state, statistics and events.

  - ### removeListener

    public final void removeListener(WorkoutSessionListener listener)
    Removes a listener.

  - ### getStatisticsSnapshot

    protected final Map<String, HealthQuantity> getStatisticsSnapshot()
    The accumulated statistics, for ports assembling the final record.

  - ### doPrepare

    protected void doPrepare(AsyncResource<Boolean> out)
    Warms up sensors. Default completes immediately.

  - ### doStart

    protected abstract void doStart(AsyncResource<Boolean> out)
    Starts platform collection.

  - ### doPause

    protected abstract void doPause(AsyncResource<Boolean> out)
    Pauses platform collection.

  - ### doResume

    protected abstract void doResume(AsyncResource<Boolean> out)
    Resumes platform collection.

  - ### doEnd

    protected abstract void doEnd(AsyncResource<WorkoutSample> out)
    Stops collection and persists the workout.

  - ### doDiscard

    protected abstract void doDiscard()
    Abandons the workout without persisting.

  - ### doAddSamples

    protected void doAddSamples(List<HealthSample> samples, AsyncResource<Boolean> out)
    Hands fed samples to the platform. Default accepts them into the shared rollup only.

  - ### setState

    protected final void setState(WorkoutSessionState newState)
    Moves to a new state and notifies listeners. Ports call this for transitions the platform initiated.

  - ### fireStatisticsUpdated

    protected final void fireStatisticsUpdated(HealthDataType type)
    Notifies listeners that a statistic changed.

  - ### fireEvent

    protected final void fireEvent(WorkoutEvent event)
    Notifies listeners of an event.

  - ### fireFailed

    protected final void fireFailed(HealthException error)
    Reports an unrecoverable failure and moves to `WorkoutSessionState.FAILED`.