Setup
Asleep.setup()은 SDK의 인증 정보를 설정하고, 필요하면 SDK가 탑재된 기기(Product)를 Asleep 서버에 등록하는 API입니다.
앱 실행 후 수면 측정을 시작하기 전에 호출하고, onComplete()를 받은 뒤 Asleep.initAsleepConfig()를 호출하세요.
Asleep.setup(context, apiKey, asleepSetupListener, productInfo) ← 인증 정보 · 기기 정보 전달
└ onComplete()
└ Asleep.initAsleepConfig(context, apiKey, userId, asleepConfigListener)
└ onSuccess(userId, asleepConfig)
└ createSleepTrackingManager → startSleepTracking
또는 beginSleepTracking
productInfo를 넘기지 않으면 기존(3.2.0)과 완전히 같이 동작합니다. Product 등록을 사용하려면 setup에 productInfo를 넘겨야 합니다.
Asleep.setup()
val productInfo = ProductInfo(
model = "MODEL_NAME",
identifierType = Asleep.ProductIdentifierType.SERIAL,
identifierValue = "SERIAL_NUMBER"
)
Asleep.setup(
context = applicationContext,
apiKey = "YOUR_API_KEY",
baseUrl = null,
callbackUrl = null,
service = null,
asleepSetupListener = object : Asleep.AsleepSetupListener {
override fun onComplete() { }
override fun onProgress(progress: Int) { }
override fun onFail(errorCode: Int, detail: String) { }
},
productInfo = productInfo
)| Parameter | Type | Description |
|---|---|---|
context | Context | 애플리케이션 컨텍스트 |
apiKey | String | 대시보드에서 발급받은 API Key |
baseUrl | String? | null이면 기본 서버를 사용합니다. 프록시 서버를 쓰는 경우 주소를 입력하세요 |
callbackUrl | String? | 수면 세션 분석 결과를 받을 서버 URL |
service | String? | 앱 이름 |
asleepSetupListener | AsleepSetupListener? | setup 결과를 받을 리스너 |
productInfo | ProductInfo? | 기기(Product) 정보. 넘기면 setup 과정에서 기기를 등록합니다. 아래 Product 등록 참고 |
Token 방식
API Key 대신 앱 인증 정보(appId · appSecret) 로 인증할 수 있습니다. setup 이후의 모든 API는 인증 방식과 관계없이 똑같이 사용합니다.
Asleep.setup(
context = applicationContext,
appId = "YOUR_APP_ID",
appSecret = "YOUR_APP_SECRET",
asleepSetupListener = asleepSetupListener,
productInfo = productInfo
)| Parameter | Type | Description |
|---|---|---|
context | Context | 애플리케이션 컨텍스트 |
appId | String | 대시보드에서 발급받은 App ID |
appSecret | String | 대시보드에서 발급받은 App Secret |
isTestEnvironment | Boolean? | 테스트 환경을 사용할 때만 true. 기본값 null |
baseUrl | String? | null이면 기본 서버를 사용합니다 |
callbackUrl | String? | 수면 세션 분석 결과를 받을 서버 URL |
service | String? | 앱 이름 |
asleepSetupListener | AsleepSetupListener? | setup 결과를 받을 리스너 |
productInfo | ProductInfo? | 기기(Product) 정보. 아래 Product 등록 참고 |
API Key 방식과의 차이
| 항목 | API Key | Token |
|---|---|---|
| 인증 헤더 | x-api-key | Authorization: Bearer |
| 토큰 갱신 | 없음 | SDK가 자동으로 갱신합니다 (만료 5분 전) |
| 인증 실패(401) | 에러 콜백 | 자동으로 다시 발급받아 재시도합니다 |
| 인증 정보 저장 | - | EncryptedSharedPreferences(AES256) |
appId또는appSecret가 빈 문자열이면 즉시onFail(11000)입니다.- 두 방식은 같은 재호출 가드를 공유합니다. API Key setup이 진행 중이면 Token setup도 무시됩니다.
- 토큰 관련 실패는
12000~12003으로 전달됩니다. 아래 에러 코드 표를 참고하세요.
| Code | Name | 상황 |
|---|---|---|
| 12000 | ERR_TOKEN_ISSUE_FAILED | 토큰 발급 실패 |
| 12001 | ERR_TOKEN_REFRESH_FAILED | 토큰 갱신 실패 |
| 12002 | ERR_TOKEN_INVALID_CREDENTIALS | 잘못된 appId / appSecret |
| 12003 | ERR_TOKEN_NETWORK_ERROR | 토큰 요청 중 네트워크 오류 |
AsleepSetupListener
interface AsleepSetupListener {
fun onComplete()
fun onProgress(progress: Int)
fun onFail(errorCode: Int, detail: String)
}- onComplete() — setup이 끝났을 때 호출됩니다.
productInfo를 넘겼다면 기기 등록까지 끝난 뒤에만 호출됩니다. - onFail(errorCode, detail) — setup이 실패했을 때 호출됩니다. 이 경우
onComplete()는 호출되지 않습니다.detail은 원인 확인(로그)용 문자열입니다. 앱 로직은 반드시errorCode로 분기하세요.
- onProgress(progress) — Product 등록 과정에서는 호출되지 않습니다. 빈 구현으로 두어도 됩니다.
호출 규칙
| 상황 | 동작 |
|---|---|
setup이 진행 중일 때 다시 setup 호출 | 무시됩니다 (예: W setup is already in progress; this call is ignored, 콜백 없음). onComplete / onFail을 받은 뒤 호출하세요. 콜백 안에서 다시 호출하는 것은 괜찮습니다 |
수면 측정 중 setup 호출 | 무시됩니다 (콜백 없음). 측정을 종료한 뒤 호출하세요 |
apiKey가 빈 문자열 | 즉시 onFail(11000) |
baseUrl 형식이 잘못됨 | 즉시 onFail(11004) |
Product 등록
Product 등록은 SDK가 탑재된 기기를 Asleep 서버에 등록하는 기능입니다. 등록해두면 서버가 어떤 세션이 어떤 기기에서 측정되었는지 기록합니다.
- 별도 API 없이
setup에productInfo를 넘기면 등록됩니다. - 등록에 성공하면 SDK가 등록 정보를 기기에 저장하고, 이후 세션 생성 · 데이터 업로드 등의 요청에 자동으로 포함합니다. 앱이 따로 다룰 값은 없습니다.
productInfo없이setup을 호출하면 등록 요청을 보내지 않습니다.
ProductInfo
data class ProductInfo(
val model: String,
val identifierType: Asleep.ProductIdentifierType,
val identifierValue: String
)
enum class ProductIdentifierType { SERIAL, MAC_ADDRESS }| Property | Type | Description |
|---|---|---|
model | String | 제품 모델명 (1~100자) |
identifierType | ProductIdentifierType | 기기를 구분하는 값의 종류. SERIAL(시리얼 번호) 또는 MAC_ADDRESS(MAC 주소) |
identifierValue | String | 시리얼 번호 또는 MAC 주소 (1~255자) |
꼭 지켜주세요
identifierValue는 기기마다 고유하고 바뀌지 않는 값을 사용하세요.- 항상 같은 형식으로 넘겨주세요. SDK는 대소문자, 구분자(
:/-), 앞뒤 공백을 변환하지 않고, 문자열이 조금이라도 다르면 다른 기기로 보고 다시 등록 요청을 보냅니다.- 빈 값, 공백만 있는 값, 길이를 넘는 값은 서버 요청 없이
onFail(13400)으로 실패합니다.
동작 방식
productInfo를 넘기면 기기 등록이 setup의 한 단계가 되고, 등록이 끝나야 나머지 단계가 진행됩니다.
Asleep.setup(context, apiKey, asleepSetupListener, productInfo)
│
├ ① 저장된 등록 정보 확인
│ 같은 API Key · 같은 productInfo로 이미 등록됨 → 등록 요청 없이 바로 통과
│
├ ② 입력값 확인
│ model / identifierValue 조건 위반 → onFail(13400)
│
├ ③ 서버에 등록 요청
│ 네트워크 오류 · 서버 오류 → 2초 · 4초 · 8초 뒤 최대 3번 재시도
│
└ ④ 성공 → (나머지 setup 단계) → onComplete()
실패 → onFail(13000 또는 13400)
| 상황 | 동작 |
|---|---|
| 처음 실행 | 서버에 등록하고 등록 정보를 저장합니다 |
다음 실행부터 (같은 API Key · 같은 productInfo) | 등록 요청 없이 바로 통과합니다 |
productInfo가 바뀜 (예: 연결된 기기 변경) | 새 productInfo로 다시 등록합니다. 성공하면 이후 생성되는 세션부터 새 기기로 기록됩니다 |
| API Key가 바뀜 | 기존 등록 정보를 지우고 새 API Key로 다시 등록합니다 |
| 앱 삭제 후 재설치 | 저장된 등록 정보도 함께 삭제되므로, 다음 setup에서 다시 등록합니다 |
앱을 실행할 때마다 같은 productInfo로 setup을 호출하세요. 두 번째 실행부터는 등록 요청 없이 바로 통과합니다.
소요 시간
등록은 setup을 멈췄다 진행하는 단계라, 네트워크가 나쁜 상태에서는 종결 콜백이 늦어집니다.
- 이미 등록된 기기: 등록 요청 없이 바로 통과합니다.
- 처음 등록: 보통 요청 한 번으로 끝납니다.
- 서버가 응답하지 않아 재시도를 모두 쓰는 경우: API Key 방식은 최대 약 90초, Token 방식은 시도마다 요청이 2건이라 최대 약 3분 뒤에
onFail(13000)이 호출됩니다. (HTTP 타임아웃 10초 · 최대 4회 시도 · 백오프 합 14초). - 4xx 거부는 재시도하지 않아 1회 왕복 안에 끝납니다.
setup 호출 직후부터 로딩 화면을 보여주는 것을 권장합니다.
측정 시작 시점
세션이 어떤 기기에서 측정되었는지는 세션이 생성될 때 결정됩니다.
- 반드시
onComplete()를 받은 뒤 측정을 시작하세요. onFail(13xxx)을 받았다면 setup은 미완료 상태입니다. 측정을 시작하지 말고 원인을 해결한 뒤setup을 다시 호출하세요.- 수면 측정 중에는
setup이 무시됩니다. 연결된 기기가 바뀌었다면 측정을 종료한 뒤 새productInfo로setup을 호출하세요.
저장 정보
- 등록 정보는 SDK 전용 EncryptedSharedPreferences에 저장됩니다.
- 등록 정보(credential)는 앱에 노출되지 않으며, SDK가 요청에 자동으로 붙입니다.
에러 코드
등록 실패는 AsleepSetupListener.onFail()로 전달되며, 앱이 다르게 대응해야 하는 두 가지 코드로 구분됩니다.
| Code | Name | 의미 | 앱이 할 일 |
|---|---|---|---|
13000 | ERR_PRODUCT_REGISTER_FAILED | 일시적인 실패. 네트워크 오류, 서버 오류(5xx), 요청 과다(429). SDK가 이미 재시도한 뒤의 결과입니다 | 네트워크 상태를 안내하고 잠시 후 setup을 다시 호출 |
13400 | ERR_PRODUCT_REGISTER_REJECTED | 거부. 입력값 오류(400), 인증 실패(401), 등록 권한 없음(403), 클라이언트 선검증 실패. 다시 시도해도 결과가 같습니다 | productInfo와 API Key 확인 |
detail은 원인 확인용 문자열이며 문구가 예고 없이 바뀔 수 있습니다.
앱 로직은 반드시 코드(13000/13400)로 분기하세요.
사용 예시
class SleepSdkController(private val context: Context) {
private val productInfo = ProductInfo(
model = "MODEL_NAME",
identifierType = Asleep.ProductIdentifierType.SERIAL,
identifierValue = deviceSerial
)
private val setupListener = object : Asleep.AsleepSetupListener {
override fun onComplete() {
// 기기 등록이 끝난 뒤에만 호출됩니다.
Asleep.initAsleepConfig(
context = context,
apiKey = "YOUR_API_KEY",
userId = userId,
asleepConfigListener = configListener
)
}
override fun onProgress(progress: Int) { }
override fun onFail(errorCode: Int, detail: String) {
when (errorCode) {
13000 -> {
// 일시적인 실패 — 네트워크 확인 후 잠시 뒤 setup 재호출
}
13400 -> {
// 거부 — productInfo / API Key 확인 (다시 시도해도 결과 동일)
}
}
}
}
private val configListener = object : Asleep.AsleepConfigListener {
override fun onSuccess(userId: String?, asleepConfig: AsleepConfig?) {
// 이제 측정을 시작할 수 있습니다.
}
override fun onFail(errorCode: Int, detail: String) { }
}
fun start() {
Asleep.setup(
context = context.applicationContext,
apiKey = "YOUR_API_KEY",
asleepSetupListener = setupListener,
productInfo = productInfo
)
}
}Updated about 3 hours ago
