SleepTrackingManager

Create manager

Asleep.createSleepTrackingManager

  • Create SleepTrackingManager that manages Sleep Tracking Feature.
fun createSleepTrackingManager(
    asleepConfig: AsleepConfig?,
    trackingListener: SleepTrackingManager.TrackingListener
): SleepTrackingManager?
Parameter NameTypeDescription
asleepConfigAsleepConfig?Enter the set value received by the callback in the initAsleepConfig call
trackingListenerTrackingListenerListener to receive callback status for Sleep Tracking

Asleep.SleepTrackingManager.TrackingListener

interface TrackingListener {
    fun onCreate()
    fun onUpload(sequence: Int)
    fun onClose(sessionId: String)
    fun onFail(errorCode: Int, detail: String)
}
  • When Sleep Tracking starts, onCreate() is called, and onUpload() is called every 30 seconds.
Parameter NameTypeDescription
sequenceIntA value that starts from 0 and increases by 1 every 30 seconds
  • When Sleep Tracking is ended, onClose()is called.
Parameter NameTypeDescription
sessionIdStringReport Result id value
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode Message

Receiving the analysis complete notification (v3.3.0)

If you create the tracking manager with a CompletableTrackingListener, the SDK notifies you through onComplete when the server analysis is finished after you stop tracking. The app does not have to check whether the report is ready by itself.

Optional parameters (recordingPath, recordingType) for saving the recording files of snoring · unstable-breathing sections have been added together.

val recordingPath = context.getExternalFilesDir(null)?.absolutePath + "/recordings"

val trackingManager = Asleep.createSleepTrackingManager(
    asleepConfig,
    object : SleepTrackingManager.CompletableTrackingListener {
        override fun onCreate(sessionId: String) { }
        override fun onUpload(sequence: Int) { }
        override fun onClose(sessionId: String) { }
        override fun onComplete(session: Session?) { }
        override fun onFail(errorCode: Int, detail: String) { }
    },
    recordingPath = recordingPath,
    recordingType = RecordingType.ALL
)
ParameterTypeDescription
asleepConfigAsleepConfig?The set value received from initAsleepConfig
completableTrackingListenerCompletableTrackingListenerListener to receive tracking events and the analysis complete notification
recordingPathString?Path to save the recording files. If omitted or null, no recording file is created. Default null
recordingTypeRecordingTypeType of recording to keep. Applied only when recordingPath is set. Default ALL

The existing way of passing a TrackingListener still works. The listener type decides the notification, and recordingPath decides the recording files.

ListenerrecordingPathAnalysis complete notification (onComplete)Recording file
TrackingListener (existing)-XX
CompletableTrackingListeneromitted (null)OX
CompletableTrackingListenerpath setOO
🚧

recordingPath / recordingType are available only on the CompletableTrackingListener overload. When you create the manager with the existing TrackingListener, those two parameters do not exist, so recording files cannot be saved.

Asleep.SleepTrackingManager.CompletableTrackingListener

interface CompletableTrackingListener {
    fun onCreate(sessionId: String)
    fun onUpload(sequence: Int)
    fun onClose(sessionId: String)
    fun onComplete(session: Session?)
    fun onFail(errorCode: Int, detail: String)
}
  • onCreate(sessionId) — Called with the session ID when the session is created. It replaces the existing TrackingListener.onCreate().
  • onComplete(session) — Called when the server analysis is finished after tracking is stopped and the result can be retrieved. You can display the result right away with sleepStages and so on, and if you also need the statistics, call Reports.getReport(sessionId).
  • The other callbacks, onUpload, onClose and onFail, are the same as before.


From stop to analysis complete

When you call stopSleepTracking(), the SDK first closes the session and then checks periodically whether the analysis is finished.

stopSleepTracking()
  │
  ├ ① Request to close the session → onClose(sessionId)
  │
  ├ ② Check for analysis completion (every 3 seconds · up to 10 times, about 30 seconds)
  │
  ├ ③-a Analysis complete → onComplete(session)
  │
  └ ③-b Not finished within 30 seconds → onFail(28000)
📘

ERR_COMPLETE_TIMEOUT(28000) is not a tracking failure. The session has already been closed normally (onClose), and it only means that the analysis did not finish within 30 seconds. Retrieve the result with Reports.getReport(sessionId) a little later.

In 3.2.0, onComplete(null) was called in the same situation. The polling has also been increased from 5 times (15 seconds) to 10 times (30 seconds).



Saving recording files (optional)

If you set recordingPath, the SDK temporarily saves the audio in 30 second units while tracking, and when the analysis is complete it keeps only the files of the snoring · unstable-breathing sections selected based on the analysis result in {recordingPath}/audio/{sessionId}/.

ItemDescription
Files keptTop 10 by intensity among the detected snoring sections + top 10 by severity among the detected unstable-breathing sections (the same section is saved only once)
File formatAAC, in 30 second units (audio_0005.aac)
Segment informationThe analysis values of every section are recorded in audio_segments.json in the same folder (including the sections whose files were not kept)
Sessions retainedThe 7 most recent (when exceeded, the oldest sessions are deleted first)
Storage spaceIf the free space is less than 200MB when tracking starts, onFail(11008) is called and tracking does not start. If it drops below 10MB during tracking, only the file saving is skipped and tracking continues
Abnormal terminationIf the session is not closed normally because of a forced termination, a drained battery and so on, no recording file is provided, and the temporary files are deleted when the next tracking starts

Asleep.RecordingType

enum class RecordingType { ALL, SNORING_ONLY, BREATH_ONLY }
ValueFiles saved
ALL (default)Snoring + unstable breathing — the same behavior as before 3.3.0
SNORING_ONLYSnoring sections only
BREATH_ONLYUnstable-breathing sections only
  • Recording of an indicator that your plan does not provide cannot be turned on with recordingType. It is meant for narrowing down the types within the range of your plan.
  • If the analysis result has no basis for the decision (including 28000, when the analysis complete notification was not received), ALL keeps every file saved during tracking, while SNORING_ONLY / BREATH_ONLY keep nothing. Tracking itself is still closed normally in this case.
  • Sessions whose analysis result cannot be used, for example when the tracking time is too short, keep no recording files.

Asleep.createRecordingFileManager()

Retrieves or deletes the saved recording files. You must pass the same recordingPath that you passed to the tracking manager.

val manager = Asleep.createRecordingFileManager(recordingPath)

val sessions = manager.getSessions()                  // List<String>, in time order
val snoringFiles = manager.getSnoringFiles(sessionId) // Snoring files (highest intensity first)
val breathFiles = manager.getBreathFiles(sessionId)   // Unstable-breathing files (highest severity first)
val allSegments = manager.getAllSegments(sessionId)   // All 30 second sections (in section index order)

manager.deleteSession(sessionId)
manager.deleteAllSessions()
data class RecordingFile(
    val filePath: String?,          // null for sections whose file was not saved
    val segmentIndex: Int,          // 30 second section index (from 0)
    val maxDb: Float,               // 0~100
    val isSnoringDetected: Boolean,
    val isBreathDetected: Boolean,
    val timestamp: String?,         // ISO 8601
    val snoreIntensity: Float,
    val breathSeverity: Float
)
PropertyTypeDescription
filePathString?Absolute path of the saved file. null for a section whose file was not kept
segmentIndexInt30 second section index (from 0)
maxDbFloatMaximum volume of the section (0~100)
isSnoringDetectedBooleanWhether snoring was detected
isBreathDetectedBooleanWhether unstable breathing was detected
timestampString?Start time of the section (ISO 8601)
snoreIntensityFloatSnoring intensity
breathSeverityFloatUnstable-breathing severity

Start sleep tracking

Asleep.SleepTrackingManager.startSleepTracking

  • Start Sleep Tracking.
fun startSleepTracking()
🚧

Follow the guideline for testing the sleep tracking

To accurately test Asleep's sleep tracking/analysis, please follow the test environment guide. Please note that sleep analysis results obtained in environments not adhering to this guide may not accurately reflect actual sleep patterns.

🔗 Check Test Environment Guideline

Sleep Analysis

Asleep.SleepTrackingManager.requestAnalysis()

  • Received the sleep data measured to date.
fun requestAnalysis(analysisListener: SleepTrackingManager.AnalysisListener)
Parameter NameTypeDescription
analysisListenerAnalysisListenersleep analysis listener

Asleep.SleepTrackingManager.AnalysisListener

interface AnalysisListener {
    fun onSuccess(session: Session)
    fun onFail(errorCode: Int, detail: String)
}
  • If success, onSuccess() is called.

Session data type

data class Session(
    val id: String,
    val state: String,
    val startTime: String,
    val endTime: String?,
    val sleepStages: List<Int?>?,
    val breathStages: List<Int>?,
    val snoringStages: List<Int?>?,
    val createdTimezone: String,
    val unexpectedEndTime: String?,
    val sleepStageProbs: List<List<Float>>?,
    val snoringStageProbs: List<List<Float>>?,
    val breathStageProbs: List<List<Float>>?,
    val measurementStartTime: String?,
    val measurementEndTime: String?
)
Parameter NameTypeDescription
idStringSleep session id
stateStringSleep session state (OPEN, CLOSED or COMPLETE)
startTimeStringStart time of the analysis range. If no range is set, it is the same as the tracking start time
endTimeString?End time of the analysis range. If no range is set, it is the same as the tracking end time
sleepStagesList<Int?>?Sleep stages
breathStagesList<Int>?Breath stability stages
snoringStagesList<Int?>?Snoring
createdTimezoneStringTimezone in which the session was created
unexpectedEndTimeString?End time when the session ended unexpectedly
sleepStageProbsList<List<Float>>?Probability values per sleep stage
snoringStageProbsList<List<Float>>?Probability values per snoring stage
breathStageProbsList<List<Float>>?Probability values per breath stage
measurementStartTimeString?The time at which the tracking (recording) actually started, regardless of the analysis range
measurementEndTimeString?The time at which the tracking (recording) actually ended, regardless of the analysis range
  • If failure, onFail() is called.
Parameter NameTypeDescription
errorCodeIntSee AsleepErrorCode
detailStringerrorCode message

Stop sleep tracking

Asleep.SleepTrackingManager.stopSleepTracking

  • Stop Sleep Tracking.
fun stopSleepTracking()

Specifying the analysis range (v3.3.0)

When you stop tracking, you can specify the range (start · end time) that the server will analyze yourself. For example, use it when you want to analyze only the "time the user fell asleep ~ time the user woke up" that the user entered.

// Analyze the whole tracking (existing)
trackingManager?.stopSleepTracking()

// Analyze only the specified range
trackingManager?.stopSleepTracking(analysisStartTime, analysisEndTime)
ParameterTypeDescription
analysisStartTimeDateAnalysis start time
analysisEndTimeDateAnalysis end time. It must be later than analysisStartTime
  • The two values are always passed together. To stop without a range, call stopSleepTracking().
  • The flow after stopping (onClose → onComplete) is the same as when no range is specified.

What changes when a range is specified

ItemChange
sleepStages / breathStages / snoringStagesOnly the specified range is returned
Session.startTime / endTimeThe start · end time of the analysis range
Session.measurementStartTime / measurementEndTimeThe time at which the tracking (recording) actually started · ended
Report.analysisInformation about the analyzed range (see the Reports page)
Recording files (when recordingPath is set)The files are selected within the analysis range. The file of a section that straddles the boundary is kept whole, not trimmed

When an invalid range is passed

Even if the range is invalid, the SDK closes the session without a range so that the session is not left open.

SituationBehavior
The start time is later than or the same as the end timeCalls onFail(11009) without a server request and then closes the session without a range. After that, onClose → onComplete proceed normally
The server rejects the range (400)The SDK requests the close again without the range. If it succeeds, the normal flow proceeds and the app is not notified separately (only a warning log is left)
The retry without the range also failsSame as an existing close failure, onFail(24xxx)

Asleep.SleepTrackingManager.forceStopSleepTracking

  • Stops Sleep Tracking immediately. It closes the session without an analysis range, and the calling thread waits until the stop processing is finished.
fun forceStopSleepTracking()


Get sleep tracking status

Asleep.SleepTrackingManager.getTrackingStatus()

fun getTrackingStatus(): TrackingStatus

Asleep.SleepTrackingManager.TrackingStatus

class TrackingStatus (var sessionId: String? = null)
Property nameTypeDescription
sessionIdString?Currently tracking session id
Available from the onCreate function of TrackingListener
Valid until the corresponding Session is closed

Did this page help you?