Class SleepSample


public final class SleepSample extends SessionSample

A sleep session, optionally broken into SleepStageInterval spans.

Stage detail is not guaranteed

A session recorded by a watch usually carries stages; one inferred by a phone usually does not, and neither did iOS before version 16. Check hasStageDetail() and fall back to showing the total duration -- drawing a hypnogram from a single "asleep" span produces an empty chart that looks like a bug.

if (night.hasStageDetail()) {
    for (SleepStageInterval iv : night.getStages()) {
        drawBand(iv.getStage(), iv.getStartMillis(), iv.getEndMillis());
    }
} else {
    showTotal(night.getDurationMillis());
}
Sessions on iOS are reassembled

HealthKit has no sleep-session object at all -- only a run of overlapping category samples. The iOS port groups them into sessions using Apple's own convention of splitting on a gap, configurable via SampleQuery.setSleepSessionGapMillis(long). That grouping is a heuristic, which is why it lives in the port and is tunable rather than being silently baked into the shared code.

  • Method Details

    • create

      public static SleepSample create(long startMillis, long endMillis)
      A session with no stage breakdown.
    • create

      public static SleepSample create(long startMillis, long endMillis, List<SleepStageInterval> stages)
      A session with stage detail. The list is copied defensively.
    • getStages

      public List<SleepStageInterval> getStages()
      The stage breakdown, in the order the platform reported it. Empty when no breakdown is available.
    • addStage

      public void addStage(SleepStageInterval interval)
      Appends a stage span. Used when building a session to write.
    • hasStageDetail

      public boolean hasStageDetail()

      true when this session carries a real stage breakdown -- that is, at least one span classified as something more specific than "asleep", "in bed" or "unknown".

      Returns false for an empty stage list and for a list containing only SleepStage.ASLEEP_UNSPECIFIED, SleepStage.AWAKE_IN_BED and SleepStage.UNKNOWN, because none of those tell you anything a hypnogram could show.

    • getDurationMillis

      public long getDurationMillis(SleepStage stage)
      The total time in stage, summed across every span.
    • getAsleepDurationMillis

      public long getAsleepDurationMillis()

      The total time spent asleep -- every span except SleepStage.AWAKE, SleepStage.AWAKE_IN_BED and SleepStage.OUT_OF_BED.

      Falls back to the whole session duration when no stages are present, which is the best available answer for a source that only reported "asleep from X to Y".

    • toString

      public String toString()
      Description copied from class: Object
      Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + '@' + Integer.toHexString(hashCode())
      Overrides:
      toString in class HealthSample