public final class SleepSample
- Object
- HealthSample
- SessionSample
- SleepSample
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());
}
Neither phone reads sleep in this release
Sleep is available on the simulator, the desktop and the JavaScript port, and on none of the mobile ones: a sleep query is refused on iOS and Android alike, so no session of this shape ever comes back from a device. Build against it by all means – but do not build a mobile screen around it yet.
The reason it is unfinished on iOS is worth knowing, because it shapes
what finishing it will look like. HealthKit has no sleep-session
object at all, only a run of overlapping category samples, so the port
has to group them into sessions itself – Apple’s own convention is to
split on a gap, which is what SampleQuery.setSleepSessionGapMillis(long)
is there to tune. That grouping is a heuristic, which is why it
belongs in the port rather than baked into the shared code.
Methods
Inherited methods
Method details
create
public static SleepSample create(long startMillis, long endMillis)create
public static SleepSample create(long startMillis, long endMillis, List<SleepStageInterval> stages)getStages
public List<SleepStageInterval> getStages()addStage
public void addStage(SleepStageInterval interval)getStageSupport
public SleepStageSupport getStageSupport()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.
How much stage detail this session carries.
Three answers rather than the boolean hasStageDetail(), because
“has stages” collapses two cases an app has to draw differently: a
session that knows only asleep-versus-awake, and one carrying a real
hypnogram. Branch on this before building the UI rather than
discovering it from an empty chart.
hasStageDetail() is kept and is exactly
getStageSupport() == SleepStageSupport.STAGED.
hasStageDetail
public boolean hasStageDetail()getDurationMillis
public long getDurationMillis(SleepStage stage)stage – the time actually covered by its
spans, so two overlapping spans of the same stage count the overlap
once.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”.
getAsleepDuration
public Duration getAsleepDuration()Time asleep in this session, as a Duration.
The millis form stays for the ports and the wire format; this is the type the rest of the framework speaks.
toString
public String toString()