# Class HealthSample

java.lang.Object
com.codename1.health.HealthSample

Direct Known Subclasses:
  `BloodPressureSample, CategorySample, QuantitySample, SeriesSample, SessionSample`

public abstract class HealthSample extends Object

The base of every health record: what it measures and when.

Concrete subclasses correspond to `HealthDataKind` -- `QuantitySample`, `CategorySample`, `SeriesSample` and the `SessionSample` family.

##### Instants and intervals

Every sample carries both a start and an end. When they are equal the sample marks an instant -- see `isInstantaneous()`. Cumulative types such as steps are always intervals; see `HealthDataType.isIntervalOnly()`.

##### Identity

`getId()` is assigned by the platform on write. It is scoped to this platform and this installation and does not survive a reinstall, so it must not be used as a primary key on your server.

`getMetadata()` is not persisted to HealthKit or Health Connect in this release. It round-trips through the local store used by the simulator, desktop and JavaScript, and it travels with a sample you hold in memory, but a sample written to a mobile platform and read back comes back without it. Health Connect has no arbitrary metadata -- only a single `clientRecordId` -- so a general map cannot be carried there at all. Correlate on your own identifier held in your own storage, keyed by whatever you can reconstruct from the sample's type, time range and value.

##### Mutability

Samples you build for a write are mutable so optional fields can be filled in before handing them to `HealthStore`. Samples returned from a query are snapshots: changing one does not change the store, and to modify stored data you delete and re-write it.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `HealthSample(HealthDataType type, long startMillis, long endMillis)`
  Creates a sample spanning `[startMillis, endMillis]`.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `equals(Object o)`
  Two samples are equal when they carry the same platform identifier.
  `final Duration`
  `getDuration()`
  How long this sample covers.
  `final long`
  `getDurationMillis()`
  The span in milliseconds; 0 for an instantaneous sample.
  `final Instant`
  `getEnd()`
  When this sample ends.
  `final long`
  `getEndMillis()`
  End, epoch millis UTC.
  `final String`
  `getId()`
  The platform-assigned identifier, or null for a sample that has not been written yet.
  `final Map<String,String>`
  `getMetadata()`
  Free-form metadata carried alongside the sample, never null.
  `final RecordingMethod`
  `getRecordingMethod()`
  How this sample was recorded.
  `final HealthSource`
  `getSource()`
  Which app and device produced this sample, or null when the platform did not report it.
  `final Instant`
  `getStart()`
  When this sample starts.
  `final long`
  `getStartMillis()`
  Inclusive start, epoch millis UTC.
  `final HealthDataType`
  `getType()`
  What this sample measures.
  `int`
  `hashCode()`
  Returns a hash code value for the object.
  `final boolean`
  `isInstantaneous()`
  `true` when this sample marks a moment rather than a span.
  `final void`
  `putMetadata(String key, String value)`
  Attaches a metadata entry.
  `final void`
  `setId(String id)`
  Sets the platform identifier.
  `final void`
  `setRecordingMethod(RecordingMethod recordingMethod)`
  Declares how this sample was recorded.
  `final void`
  `setSource(HealthSource source)`
  Sets the originating source.
  `String`
  `toString()`
  Returns a string representation of the object.

  ### Methods inherited from class Object

  `clone, getClass, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### HealthSample

    protected HealthSample(HealthDataType type, long startMillis, long endMillis)

    Creates a sample spanning `[startMillis, endMillis]`.

    ###### Throws

    - `IllegalArgumentException`: if `type` is null or the end precedes the start.

- ## Method Details

  - ### getType

    public final HealthDataType getType()
    What this sample measures.

  - ### getStartMillis

    public final long getStartMillis()
    Inclusive start, epoch millis UTC.

  - ### getEndMillis

    public final long getEndMillis()
    End, epoch millis UTC. Equal to the start for an instantaneous sample.

  - ### getStart

    public final Instant getStart()

    When this sample starts.

    The millis accessors stay, and are what the ports and the wire format use: a series can hold tens of thousands of measurements and an `Instant` per point is an allocation per point. For a single sample this is the type the rest of the framework speaks -- `com.codename1.calendar` included -- so it is what the public API hands out.

  - ### getEnd

    public final Instant getEnd()
    When this sample ends. Equal to `getStart()` for an instantaneous sample.

  - ### getDuration

    public final Duration getDuration()
    How long this sample covers. Zero for an instantaneous sample.

  - ### isInstantaneous

    public final boolean isInstantaneous()
    `true` when this sample marks a moment rather than a span.

  - ### getDurationMillis

    public final long getDurationMillis()
    The span in milliseconds; 0 for an instantaneous sample.

  - ### getId

    public final String getId()
    The platform-assigned identifier, or null for a sample that has not been written yet. See the class documentation on identity before persisting this anywhere.

  - ### setId

    public final void setId(String id)
    Sets the platform identifier. Called by ports when reading; setting it on a sample you are about to write has no effect.

  - ### getSource

    public final HealthSource getSource()
    Which app and device produced this sample, or null when the platform did not report it.

  - ### setSource

    public final void setSource(HealthSource source)
    Sets the originating source. Called by ports when reading.

  - ### getRecordingMethod

    public final RecordingMethod getRecordingMethod()
    How this sample was recorded. Never null; defaults to `RecordingMethod.UNKNOWN`.

  - ### setRecordingMethod

    public final void setRecordingMethod(RecordingMethod recordingMethod)
    Declares how this sample was recorded. Worth setting on writes -- other apps use it to decide how much to trust a value.

  - ### getMetadata

    public final Map<String,String> getMetadata()

    Free-form metadata carried alongside the sample, never null.

    Not a place for a correlation identifier, tempting as it looks. It round-trips through the local and simulator stores but is not written to HealthKit or Health Connect in this release, so on a phone it is gone the moment the sample is read back -- and `getId()` is no substitute either, being platform-assigned and unstable across a reinstall. Keep the identifier in your own storage and correlate on that.

  - ### putMetadata

    public final void putMetadata(String key, String value)
    Attaches a metadata entry. A null value removes the key.

  - ### equals

    public boolean equals(Object o)
    Two samples are equal when they carry the same platform identifier. Samples that have not been written yet have no identifier and are therefore only equal to themselves.
    Overrides:
      `equals` in class `Object`

  - ### hashCode

    public int hashCode()
    Description copied from class: `Object`
    Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable. The general contract of hashCode is: Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
    Overrides:
      `hashCode` in class `Object`

  - ### 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 `Object`