SleepTrackingManager

Create manager

Asleep.createSleepTrackingManager

  • Sleep Tracking을 관리하는 SleepTrackingManager를 생성합니다.
fun createSleepTrackingManager(
    asleepConfig: AsleepConfig?, 
    trackingListener: SleepTrackingManager.TrackingListener
): SleepTrackingManager?
Parameter NameTypeDescription
asleepConfigAsleepConfig?initAsleepConfig 호출에서 콜백받은 설정 값을 입력
trackingListenerTrackingListenerSleep Tracking에 대한 상태를 콜백 받을 수 있는 리스너

Asleep.SleepTrackingManager.TrackingListener

interface TrackingListener {
    fun onCreate()
    fun onUpload(sequence: Int)
    fun onClose(sessionId: String)
    fun onFail(errorCode: Int, detail: String)
}
  • Sleep Tracking이 시작되면 onCreate()가 호출되고 30초마다 onUpload()가 호출됩니다.
Parameter NameTypeDescription
sequenceInt0부터 시작하여 30초마다 1씩 증가된 값
  • Sleep Tracking이 종료되면 onClose()가 호출됩니다.
Parameter NameTypeDescription
sessionIdStringReport 결과 조회를 위한 id 값
  • 실패 시, onFail()이 호출됩니다.
Parameter NameTypeDescription
errorCodeIntAsleepErrorCode 참조
detailStringerrorCode에 관련된 메세지

분석 완료 알림 받기 (v3.3.0)

CompletableTrackingListener 를 넘겨 측정 매니저를 만들면, 측정을 종료한 뒤 서버 분석이 끝났을 때 onComplete 로 알려줍니다. 앱이 리포트가 준비됐는지 직접 확인할 필요가 없습니다.

코골이 · 무호흡 구간의 녹음 파일을 저장하는 선택 파라미터(recordingPath, recordingType)도 함께 추가되었습니다.

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?initAsleepConfig 에서 받은 설정
completableTrackingListenerCompletableTrackingListener측정 이벤트와 분석 완료 알림을 받을 리스너
recordingPathString?녹음 파일을 저장할 경로. 생략하거나 null 이면 녹음 파일을 만들지 않습니다. 기본값 null
recordingTypeRecordingType남길 녹음 종류. recordingPath 가 있을 때만 적용됩니다. 기본값 ALL

기존 TrackingListener 를 넘기는 방식은 그대로 동작합니다. 리스너 종류가 알림을, recordingPath 가 녹음 파일을 결정합니다.

리스너recordingPath분석 완료 알림 (onComplete)녹음 파일
TrackingListener (기존)-XX
CompletableTrackingListener생략 (null)OX
CompletableTrackingListener경로 지정OO
🚧

recordingPath / recordingTypeCompletableTrackingListener 오버로드에만 있습니다. 기존 TrackingListener 로 만들 때는 두 파라미터 자체가 없어 녹음 파일을 저장할 수 없습니다.

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) — 세션이 생성되면 세션 ID 와 함께 호출됩니다. 기존 TrackingListener.onCreate() 를 대신합니다.
  • onComplete(session) — 측정 종료 후 서버 분석이 끝나 결과를 조회할 수 있을 때 호출됩니다. sleepStages 등으로 바로 결과를 표시할 수 있고, 통계까지 필요하면 Reports.getReport(sessionId) 를 호출하세요.
  • 그 외 onUpload, onClose, onFail 은 기존과 같습니다.


종료 후 분석 완료까지

stopSleepTracking() 을 호출하면 SDK 는 세션을 먼저 종료한 뒤, 분석이 끝났는지 주기적으로 확인합니다.

stopSleepTracking()
  │
  ├ ① 세션 종료 요청 → onClose(sessionId)
  │
  ├ ② 분석 완료 확인 (3초 간격 · 최대 10회, 약 30초)
  │
  ├ ③-a 분석 완료 → onComplete(session)
  │
  └ ③-b 30초 안에 끝나지 않음 → onFail(28000)
📘

ERR_COMPLETE_TIMEOUT(28000)은 측정 실패가 아닙니다. 세션은 이미 정상 종료(onClose)되었고, 분석이 30초 안에 끝나지 않았다는 뜻입니다. 잠시 후 Reports.getReport(sessionId) 로 결과를 조회하세요.

3.2.0 에서는 같은 상황에서 onComplete(null) 이 호출되었습니다. 폴링도 5회(15초)에서 10회(30초)로 늘어났습니다.



녹음 파일 저장 (선택)

recordingPath 를 지정하면 측정 중 오디오를 30초 단위로 임시 저장하고, 분석이 완료되면 분석 결과를 기준으로 코골이 · 무호흡 구간 파일만 골라 {recordingPath}/audio/{sessionId}/ 에 남깁니다.

항목내용
남기는 파일코골이 감지 구간 중 강도 상위 10개 + 무호흡 감지 구간 중 심각도 상위 10개 (같은 구간은 1개만 저장)
파일 형식AAC, 30초 단위 (audio_0005.aac)
세그먼트 정보같은 폴더의 audio_segments.json 에 전체 구간의 분석 값이 기록됩니다 (파일을 남기지 않은 구간 포함)
보관 세션 수최근 7개 (넘으면 오래된 세션부터 삭제)
저장 공간측정 시작 시 여유 공간이 200MB 미만이면 onFail(11008) 을 호출하고 측정을 시작하지 않습니다. 측정 중 10MB 미만이 되면 파일 저장만 건너뛰고 측정은 계속합니다
비정상 종료강제 종료 · 배터리 방전 등으로 정상 종료되지 않으면 녹음 파일을 제공하지 않으며, 임시 파일은 다음 측정 시작 시 삭제됩니다

Asleep.RecordingType

enum class RecordingType { ALL, SNORING_ONLY, BREATH_ONLY }
저장되는 파일
ALL (기본값)코골이 + 무호흡 — 3.3.0 이전과 같은 동작
SNORING_ONLY코골이 구간만
BREATH_ONLY무호흡 구간만
  • 플랜에서 제공하지 않는 지표의 녹음은 recordingType 으로 켜지지 않습니다. 플랜 범위 안에서 종류를 좁히는 용도입니다.
  • 분석 결과에 판정 근거가 없는 경우(분석 완료를 받지 못한 28000 포함), ALL 은 측정 중 저장한 파일을 모두 남기고 SNORING_ONLY / BREATH_ONLY 는 아무것도 남기지 않습니다. 이때도 측정 자체는 정상 종료됩니다.
  • 측정 시간이 너무 짧은 경우 등 분석 결과를 쓸 수 없는 세션은 녹음 파일을 남기지 않습니다.

Asleep.createRecordingFileManager()

저장된 녹음 파일을 조회하거나 삭제합니다. 측정에 넘긴 것과 같은 recordingPath 를 넘겨야 합니다.

val manager = Asleep.createRecordingFileManager(recordingPath)

val sessions = manager.getSessions()                  // List<String>, 시간순
val snoringFiles = manager.getSnoringFiles(sessionId) // 코골이 파일 (강도 높은 순)
val breathFiles = manager.getBreathFiles(sessionId)   // 무호흡 파일 (심각도 높은 순)
val allSegments = manager.getAllSegments(sessionId)   // 전체 30초 구간 (구간 번호 순)

manager.deleteSession(sessionId)
manager.deleteAllSessions()
data class RecordingFile(
    val filePath: String?,          // 파일이 저장되지 않은 구간은 null
    val segmentIndex: Int,          // 30초 구간 번호 (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?저장된 파일의 절대 경로. 파일을 남기지 않은 구간은 null
segmentIndexInt30초 구간 번호 (0부터)
maxDbFloat구간의 최대 음량 (0~100)
isSnoringDetectedBoolean코골이 감지 여부
isBreathDetectedBoolean무호흡 감지 여부
timestampString?구간 시작 시각 (ISO 8601)
snoreIntensityFloat코골이 강도
breathSeverityFloat무호흡 심각도

Start sleep tracking

Asleep.SleepTrackingManager.startSleepTracking

  • Sleep Tracking을 시작합니다.
fun startSleepTracking()

Sleep Analysis

Asleep.SleepTrackingManager.requestAnalysis()

  • 현재까지 측정된 결과를 받아옵니다.
fun requestAnalysis(analysisListener: SleepTrackingManager.AnalysisListener)
Parameter NameTypeDescription
analysisListenerAnalysisListenersleep analysis에 대한 리스너

Asleep.SleepTrackingManager.AnalysisListener

interface AnalysisListener {
    fun onSuccess(session: Session)
    fun onFail(errorCode: Int, detail: String)
}
  • 성공 시, onSuccess()를 호출합니다.

Session data type

data class Session(
    val id: String?,
    val state: String?,
    val startTime: String?,
    val endTime: String?,
    val sleepStages: List<Int?>?,
    val snoringStages: List<Int?>?,
    val measurementStartTime: String?,
    val measurementEndTime: String?
)
Parameter NameTypeDescription
idString?수면 세션 id
stateString?세션의 상태 ( OPEN, CLOSED or COMPLETE)
startTimeString?분석 구간의 시작 시각. 구간을 지정하지 않았다면 측정 시작 시각과 같습니다
endTimeString?분석 구간의 종료 시각. 구간을 지정하지 않았다면 측정 종료 시각과 같습니다
sleepStagesList<Int?>?수면 단계
snoringStagesList<Int?>?코골이
measurementStartTimeString?분석 구간과 관계없이 실제로 측정(녹음)이 시작된 시각
measurementEndTimeString?분석 구간과 관계없이 실제로 측정(녹음)이 종료된 시각
  • 실패 시, onFail()이 호출됩니다.
Parameter NameTypeDescription
errorCodeIntAsleepErrorCode 참조
detailStringerrorCode에 관련된 메세지

Stop sleep tracking

Asleep.SleepTrackingManager.stopSleepTracking

  • Sleep Tracking을 정지합니다.
fun stopSleepTracking()

분석 구간 지정 (v3.3.0)

측정을 종료할 때 서버가 분석할 구간(시작 · 종료 시각) 을 직접 지정할 수 있습니다. 예를 들어 사용자가 입력한 "잠든 시각 ~ 일어난 시각"만 분석할 때 사용합니다.

// 측정 전체 분석 (기존)
trackingManager?.stopSleepTracking()

// 지정한 구간만 분석
trackingManager?.stopSleepTracking(analysisStartTime, analysisEndTime)
ParameterTypeDescription
analysisStartTimeDate분석 시작 시각
analysisEndTimeDate분석 종료 시각. analysisStartTime 보다 늦어야 합니다
  • 두 값은 항상 함께 넘깁니다. 구간 없이 종료하려면 stopSleepTracking() 을 호출하세요.
  • 종료 이후 흐름(onCloseonComplete)은 구간을 지정하지 않았을 때와 같습니다.

구간을 지정하면 달라지는 점

항목변화
sleepStages / breathStages / snoringStages지정한 구간만큼만 내려옵니다
Session.startTime / endTime분석 구간의 시작 · 종료 시각
Session.measurementStartTime / measurementEndTime실제로 측정(녹음)이 시작 · 종료된 시각
Report.analysis분석한 구간 정보 (Reports 페이지 참고)
녹음 파일 (recordingPath 지정 시)분석 구간 안에서 파일을 고릅니다. 경계에 걸친 구간의 파일은 잘리지 않고 통째로 보관됩니다

잘못된 구간을 넘겼을 때

구간이 잘못되었더라도 세션이 열린 채로 남지 않도록, SDK 는 구간 없이 세션을 종료합니다.

상황동작
시작 시각이 종료 시각보다 늦거나 같음서버 요청 없이 onFail(11009) 를 호출한 뒤 구간 없이 세션을 종료합니다. 이후 onCloseonComplete 는 정상으로 진행됩니다
서버가 구간을 거부(400)SDK 가 구간 없이 다시 종료를 요청합니다. 성공하면 정상 흐름으로 진행되며, 앱에는 별도로 알리지 않습니다 (경고 로그만 남음)
구간 없는 재요청도 실패기존 종료 실패와 같이 onFail(24xxx)


🚧

수면 측정 테스트 시 안내 사항을 따라주시기 바랍니다.

Asleep의 수면 측정/분석 기능을 정확하게 테스트하려면, 
테스트 환경 가이드를 반드시 따라주시기 바랍니다. 이 가이드를 준수하지 않은 환경에서 얻은 수면 분석 결과는 실제 수면 패턴과 정확하게 일치하지 않을 수 있습니다.

🔗 Test Environment Guideline 확인하기

Get sleep tracking status

Asleep.SleepTrackingManager.getTrackingStatus()

fun getTrackingStatus(): TrackingStatus

Asleep.SleepTrackingManager.TrackingStatus

class TrackingStatus (var sessionId: String? = null)
Property nameTypeDescription
sessionIdString?현재 Tracking 중인 session id
TrackingListener의 onCreate 함수에서부터
사용할 수 있으며 해당 Session이 Close 될 때까지 유효하다

📘

SleepTrackingManager를 사용하려면 포그라운드 서비스에서 동작되어야 오랜시간 측정이 가능합니다. Sample App을 참조하세요.


Did this page help you?