I'm trying to read sleep data from Google Fit. The sessionsClient reads from Fit successfully, however, it does not return any sessions in response.sessions even though there are sleep sessions logged in Fit. Due to the API update being relatively recent, I am unable to find any resources online to resolve this so any suggestions would be appreciated.
The response returns this:
SessionReadResult{status=Status{statusCode=SUCCESS, resolution=null}, sessions=[], sessionDataSets=[]}
I followed the updated documentation from https://developers.google.com/fit/scenarios/read-sleep-data#android
Here is the sleep data logged in Fit:
And the code used:
//Sets the start time to the month previous so data is got from then
val endTime = LocalDateTime.now().atZone(ZoneId.systemDefault())
val startTime = endTime.minusMonths(1)
//Sleep session request
val request = SessionReadRequest.Builder()
.readSessionsFromAllApps()
.includeSleepSessions()
.read(DataType.TYPE_SLEEP_SEGMENT)
.enableServerQueries()
.setTimeInterval(startTime.toEpochSecond(), endTime.toEpochSecond(), TimeUnit.MILLISECONDS)
.build()
//Set fitnessOptions
val fitnessOptions = FitnessOptions.builder()
.accessSleepSessions(FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_SLEEP_SEGMENT, FitnessOptions.ACCESS_READ)
.build()
//Get permissions from user
if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(this), fitnessOptions)) {
GoogleSignIn.requestPermissions(
this,
RC_REQUEST_SLEEP_AND_CONTINUE_SUBSCRIPTION,
GoogleSignIn.getLastSignedInAccount(this),
fitnessOptions);
}
//Make read request and process response
getSessionsClient(this, GoogleSignIn.getAccountForExtension(this, fitnessOptions))
.readSession(request)
.addOnSuccessListener { response ->
Log.i(TAG, "Read Success")
for (session in response.sessions) {
val sessionStart = session.getStartTime(TimeUnit.MILLISECONDS)
val sessionEnd = session.getEndTime(TimeUnit.MILLISECONDS)
Log.i(TAG, "Sleep between $sessionStart and $sessionEnd")
// If the sleep session has finer granularity sub-components, extract them:
val dataSets = response.getDataSet(session)
for (dataSet in dataSets) {
for (point in dataSet.dataPoints) {
val sleepStageVal = point.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
val sleepStage = SLEEP_STAGE_NAMES[sleepStageVal]
val segmentStart = point.getStartTime(TimeUnit.MILLISECONDS)
val segmentEnd = point.getEndTime(TimeUnit.MILLISECONDS)
Log.i(TAG, "\t* Type $sleepStage between $segmentStart and $segmentEnd")
}
}
}
setBarChartValues(pTime)
}
.addOnFailureListener { e ->
Log.i(TAG, "Failure Response: ", e)
}
}
I have resolved this by using the sample project from Google found here: https://github.com/android/fit-samples/blob/main/SleepKotlin/app/src/main/java/com/google/android/gms/fit/samples/basicsleepkotlin/MainActivity.kt
It has a lot more code/steps than described in the documentation, especially regarding the new sleep permissions.