Get Started
Requirements
Minimum requirements on AsleepTrack SDK for Android
- Android 7.0 (API level 24) or higher
- Java 1.8 or higher
- Android Gradle plugin 8.0 or higher
API Key
- The API key is required to use the Asleep Track SDK.
- For how to issue an API key, see this link [Generate API key]
Getting Ready
Install AsleepTrack SDK and Settings
- Create a project using Android Studio.
- Open the AndroidManifest.xml file to add permissions.
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
- Open the app-level build.gradle file and add lifecycle-service, okhttp, gson, and asleepsdk.
dependencies {
...
implementation("androidx.lifecycle:lifecycle-service:2.8.7")
implementation("com.squareup.okhttp3:okhttp:4.11.0")
implementation("com.google.code.gson:gson:2.10")
implementation("ai.asleep:asleepsdk:3.1.0")
}
dependencies {
...
implementation 'androidx.lifecycle:lifecycle-service:2.8.7'
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
implementation 'com.google.code.gson:gson:2.10'
implementation 'ai.asleep:asleepsdk:3.1.0'
}
Sleep Tracking with AsleepTrack SDK
Permission Acquisition
- Acquire the required permissions: RECORD_AUDIO and POST_NOTIFICATIONS (for Android 13 and above).
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
ActivityCompat.requestPermissions(
this@MainActivity,
arrayOf(android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.POST_NOTIFICATIONS),
0)
...
}
UI
- Create buttons for Init, Begin, End, and Report to be displayed on the screen.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_init"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:text="init"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_begin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:text="begin"
app:layout_constraintEnd_toStartOf="@+id/btn_end"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_init" />
<Button
android:id="@+id/btn_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:text="end"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_begin"
app:layout_constraintTop_toBottomOf="@+id/btn_init" />
<Button
android:id="@+id/btn_report"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="report"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_init" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Declare the buttons as variables.
...
private lateinit var btnInit: Button
private lateinit var btnBegin: Button
private lateinit var btnEnd: Button
private lateinit var btnReport: Button
...
btnInit = findViewById(R.id.btn_init)
btnBegin = findViewById(R.id.btn_begin)
btnEnd = findViewById(R.id.btn_end)
btnReport = findViewById(R.id.btn_report)
AsleepTrack SDK Initialization
- Replace [YOUR API KEY] in apiKey with the actual issued API Key.
- If userId is null, the SDK will generate a new userId.
- In a real app implementation, the generated userId should be stored and retrieved as needed.
- service: If the app has a specific service name, enter it here.
- asleepConfigListener: Provides a callback for initialization success or failure.
- On success, userId and asleepConfig are returned.
val TAG = "[AsleepSDK]"
private var createdUserId: String? = null
private var createdAsleepConfig: AsleepConfig? = null
private var createdSessionId: String? = null
...
btnInit.setOnClickListener {
Asleep.initAsleepConfig(
context = this,
apiKey = "[YOUR API KEY]",
userId = null,
service = "Test App",
asleepConfigListener = object: Asleep.AsleepConfigListener {
override fun onFail(errorCode: Int, detail: String) {
Log.d(TAG, "initAsleepConfig onFail $errorCode $detail")
}
override fun onSuccess(userId: String?, asleepConfig: AsleepConfig?) {
Log.d(TAG, "initAsleepConfig onSuccess $userId")
createdUserId = userId
createdAsleepConfig = asleepConfig
}
})
}
Begin SleepTracking
- Start sleep tracking.
- Pass the
asleepConfig
generated frominitAsleepConfig
and theasleepTrackingListener
to monitor the sleep tracking status. - When tracking begins, the
onStart()
callback is triggered. - The
onPerform()
callback is called every 30 seconds to provide progress updates. - When tracking ends, the
onFinish()
callback is triggered.
- Pass the
btnBegin.setOnClickListener {
createdAsleepConfig?.let { asleepConfig ->
Asleep.beginSleepTracking(
asleepConfig = asleepConfig,
asleepTrackingListener = object : Asleep.AsleepTrackingListener {
override fun onFail(errorCode: Int, detail: String) {
Log.d(TAG, "beginSleepTracking onFail $errorCode $detail")
}
override fun onFinish(sessionId: String?) {
Log.d(TAG, "beginSleepTracking onFinish $sessionId")
}
override fun onPerform(sequence: Int) {
Log.d(TAG, "beginSleepTracking onPerform $sequence")
}
override fun onStart(sessionId: String) {
Log.d(TAG, "beginSleepTracking onStart $sessionId")
createdSessionId = sessionId
}
})
}
}
End SleepTracking
- End sleep tracking.
btnEnd.setOnClickListener {
Asleep.endSleepTracking()
}
Get Report
- Retrieve the recorded sleep data.
- Create a
Reports
object by passing theasleepConfig
generated frominitAsleepConfig
. - Provide the
sessionId
that was created during sleep tracking.
- Create a
btnReport.setOnClickListener {
createdSessionId?.let { sessionId ->
val reports = Asleep.createReports(createdAsleepConfig)
reports?.getReport(
sessionId = sessionId,
reportListener = object : Reports.ReportListener {
override fun onFail(errorCode: Int, detail: String) {
Log.d(TAG, "getReport onFail $errorCode $detail")
}
override fun onSuccess(report: Report?) {
Log.d(TAG, "getReport onSuccess $report")
}
})
}
}
Logcat Verification
- If the
logcat
logs show thatuserId
,sessionId
, andreport
have been successfully created as shown below, the SDK is functioning correctly.
Important Considerations for App Development
Using Foreground Service
For sleep tracking, the app must continuously record, process data, and perform network operations throughout the night.
To prevent interruptions, it is essential to implement a Foreground Service in your app.
Refer to the Android Foreground Service Guide for more details.Our SDK supports two development approaches:
- Begin-End Method
- The foreground service is built into the SDK, abstracting all sleep tracking operations.
- Developers do not need to implement a foreground service in the app.
- Simply call
beginSleepTracking()
andendSleepTracking()
to implement sleep tracking easily.- Refer to the Begin-End Sample App.
- SleepTrackingManager Method
- This approach provides more control by allowing developers to implement the foreground service directly.
- While it is more complex, it is useful for controlling hardware based on sleep stages or implementing custom actions.
- Refer to the FGS Process Separation Sample App.
- Choose the method that best fits your app’s requirements.
Recommended: In-App Update Feature
- In-App Update Guide
- If an Android app update occurs automatically after sleep tracking starts, the app may close unexpectedly, causing an abnormal session termination.
- To avoid this, use In-App Updates, which allow users to update the app in advance, preventing unintended interruptions.
Battery Optimization Exception
- Doze-Standby Guide
- To ensure stable sleep tracking, battery optimization exceptions are required.
- This prevents the device from entering Doze Mode during sleep tracking.
- The permission is set using
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
.
Updated 11 days ago
What’s Next