SleepTrackingManager
Create manager
Asleep.createSleepTrackingManager
- Sleep Tracking을 관리하는 SleepTrackingManager를 생성합니다.
fun createSleepTrackingManager(
asleepConfig: AsleepConfig?,
trackingListener: SleepTrackingManager.TrackingListener
): SleepTrackingManager?| Parameter Name | Type | Description |
|---|---|---|
| asleepConfig | AsleepConfig? | initAsleepConfig 호출에서 콜백받은 설정 값을 입력 |
| trackingListener | TrackingListener | Sleep 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 Name | Type | Description |
|---|---|---|
| sequence | Int | 0부터 시작하여 30초마다 1씩 증가된 값 |
- Sleep Tracking이 종료되면 onClose()가 호출됩니다.
| Parameter Name | Type | Description |
|---|---|---|
| sessionId | String | Report 결과 조회를 위한 id 값 |
- 실패 시, onFail()이 호출됩니다.
| Parameter Name | Type | Description |
|---|---|---|
| errorCode | Int | AsleepErrorCode 참조 |
| detail | String | errorCode에 관련된 메세지 |
분석 완료 알림 받기 (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
)| Parameter | Type | Description |
|---|---|---|
asleepConfig | AsleepConfig? | initAsleepConfig 에서 받은 설정 |
completableTrackingListener | CompletableTrackingListener | 측정 이벤트와 분석 완료 알림을 받을 리스너 |
recordingPath | String? | 녹음 파일을 저장할 경로. 생략하거나 null 이면 녹음 파일을 만들지 않습니다. 기본값 null |
recordingType | RecordingType | 남길 녹음 종류. recordingPath 가 있을 때만 적용됩니다. 기본값 ALL |
기존 TrackingListener 를 넘기는 방식은 그대로 동작합니다. 리스너 종류가 알림을, recordingPath 가 녹음 파일을 결정합니다.
| 리스너 | recordingPath | 분석 완료 알림 (onComplete) | 녹음 파일 |
|---|---|---|---|
TrackingListener (기존) | - | X | X |
CompletableTrackingListener | 생략 (null) | O | X |
CompletableTrackingListener | 경로 지정 | O | O |
recordingPath/recordingType은CompletableTrackingListener오버로드에만 있습니다. 기존TrackingListener로 만들 때는 두 파라미터 자체가 없어 녹음 파일을 저장할 수 없습니다.
Asleep.SleepTrackingManager.CompletableTrackingListener
Asleep.SleepTrackingManager.CompletableTrackingListenerinterface 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
Asleep.RecordingTypeenum class RecordingType { ALL, SNORING_ONLY, BREATH_ONLY }| 값 | 저장되는 파일 |
|---|---|
ALL (기본값) | 코골이 + 무호흡 — 3.3.0 이전과 같은 동작 |
SNORING_ONLY | 코골이 구간만 |
BREATH_ONLY | 무호흡 구간만 |
- 플랜에서 제공하지 않는 지표의 녹음은
recordingType으로 켜지지 않습니다. 플랜 범위 안에서 종류를 좁히는 용도입니다. - 분석 결과에 판정 근거가 없는 경우(분석 완료를 받지 못한 28000 포함),
ALL은 측정 중 저장한 파일을 모두 남기고SNORING_ONLY/BREATH_ONLY는 아무것도 남기지 않습니다. 이때도 측정 자체는 정상 종료됩니다. - 측정 시간이 너무 짧은 경우 등 분석 결과를 쓸 수 없는 세션은 녹음 파일을 남기지 않습니다.
Asleep.createRecordingFileManager()
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
)| Property | Type | Description |
|---|---|---|
filePath | String? | 저장된 파일의 절대 경로. 파일을 남기지 않은 구간은 null |
segmentIndex | Int | 30초 구간 번호 (0부터) |
maxDb | Float | 구간의 최대 음량 (0~100) |
isSnoringDetected | Boolean | 코골이 감지 여부 |
isBreathDetected | Boolean | 무호흡 감지 여부 |
timestamp | String? | 구간 시작 시각 (ISO 8601) |
snoreIntensity | Float | 코골이 강도 |
breathSeverity | Float | 무호흡 심각도 |
Start sleep tracking
Asleep.SleepTrackingManager.startSleepTracking
- Sleep Tracking을 시작합니다.
fun startSleepTracking()Sleep Analysis
Asleep.SleepTrackingManager.requestAnalysis()
- 현재까지 측정된 결과를 받아옵니다.
fun requestAnalysis(analysisListener: SleepTrackingManager.AnalysisListener)| Parameter Name | Type | Description |
|---|---|---|
| analysisListener | AnalysisListener | sleep 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 Name | Type | Description |
|---|---|---|
| id | String? | 수면 세션 id |
| state | String? | 세션의 상태 ( OPEN, CLOSED or COMPLETE) |
| startTime | String? | 분석 구간의 시작 시각. 구간을 지정하지 않았다면 측정 시작 시각과 같습니다 |
| endTime | String? | 분석 구간의 종료 시각. 구간을 지정하지 않았다면 측정 종료 시각과 같습니다 |
| sleepStages | List<Int?>? | 수면 단계 |
| snoringStages | List<Int?>? | 코골이 |
| measurementStartTime | String? | 분석 구간과 관계없이 실제로 측정(녹음)이 시작된 시각 |
| measurementEndTime | String? | 분석 구간과 관계없이 실제로 측정(녹음)이 종료된 시각 |
- 실패 시, onFail()이 호출됩니다.
| Parameter Name | Type | Description |
|---|---|---|
| errorCode | Int | AsleepErrorCode 참조 |
| detail | String | errorCode에 관련된 메세지 |
Stop sleep tracking
Asleep.SleepTrackingManager.stopSleepTracking
- Sleep Tracking을 정지합니다.
fun stopSleepTracking()분석 구간 지정 (v3.3.0)
측정을 종료할 때 서버가 분석할 구간(시작 · 종료 시각) 을 직접 지정할 수 있습니다. 예를 들어 사용자가 입력한 "잠든 시각 ~ 일어난 시각"만 분석할 때 사용합니다.
// 측정 전체 분석 (기존)
trackingManager?.stopSleepTracking()
// 지정한 구간만 분석
trackingManager?.stopSleepTracking(analysisStartTime, analysisEndTime)| Parameter | Type | Description |
|---|---|---|
analysisStartTime | Date | 분석 시작 시각 |
analysisEndTime | Date | 분석 종료 시각. analysisStartTime 보다 늦어야 합니다 |
- 두 값은 항상 함께 넘깁니다. 구간 없이 종료하려면
stopSleepTracking()을 호출하세요. - 종료 이후 흐름(
onClose→onComplete)은 구간을 지정하지 않았을 때와 같습니다.
구간을 지정하면 달라지는 점
| 항목 | 변화 |
|---|---|
sleepStages / breathStages / snoringStages | 지정한 구간만큼만 내려옵니다 |
Session.startTime / endTime | 분석 구간의 시작 · 종료 시각 |
Session.measurementStartTime / measurementEndTime | 실제로 측정(녹음)이 시작 · 종료된 시각 |
Report.analysis | 분석한 구간 정보 (Reports 페이지 참고) |
녹음 파일 (recordingPath 지정 시) | 분석 구간 안에서 파일을 고릅니다. 경계에 걸친 구간의 파일은 잘리지 않고 통째로 보관됩니다 |
잘못된 구간을 넘겼을 때
구간이 잘못되었더라도 세션이 열린 채로 남지 않도록, SDK 는 구간 없이 세션을 종료합니다.
| 상황 | 동작 |
|---|---|
| 시작 시각이 종료 시각보다 늦거나 같음 | 서버 요청 없이 onFail(11009) 를 호출한 뒤 구간 없이 세션을 종료합니다. 이후 onClose → onComplete 는 정상으로 진행됩니다 |
| 서버가 구간을 거부(400) | SDK 가 구간 없이 다시 종료를 요청합니다. 성공하면 정상 흐름으로 진행되며, 앱에는 별도로 알리지 않습니다 (경고 로그만 남음) |
| 구간 없는 재요청도 실패 | 기존 종료 실패와 같이 onFail(24xxx) |
수면 측정 테스트 시 안내 사항을 따라주시기 바랍니다.Asleep의 수면 측정/분석 기능을 정확하게 테스트하려면, 테스트 환경 가이드를 반드시 따라주시기 바랍니다. 이 가이드를 준수하지 않은 환경에서 얻은 수면 분석 결과는 실제 수면 패턴과 정확하게 일치하지 않을 수 있습니다.
🔗 Test Environment Guideline 확인하기
Get sleep tracking status
Asleep.SleepTrackingManager.getTrackingStatus()
fun getTrackingStatus(): TrackingStatusAsleep.SleepTrackingManager.TrackingStatus
class TrackingStatus (var sessionId: String? = null)| Property name | Type | Description |
|---|---|---|
| sessionId | String? | 현재 Tracking 중인 session id TrackingListener의 onCreate 함수에서부터 사용할 수 있으며 해당 Session이 Close 될 때까지 유효하다 |
SleepTrackingManager를 사용하려면 포그라운드 서비스에서 동작되어야 오랜시간 측정이 가능합니다. Sample App을 참조하세요.
Updated about 24 hours ago
