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 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.