Skip to content

Commit

Permalink
[Health] improve support for sleep stages (#1026)
Browse files Browse the repository at this point in the history
* Remove Google Fit and imports from Android code

* Formatting

* Remove Google Fit column from readme

* Remove support for Google Fit types not supported by Health Connect

* Remove more Google Fit workout types

* Remove references to Google Fit, remove `useHealthConnectIfAvailable`

* Remove `disconect` method channel

* Remove `flowRate` from `writeBloodOxygen` as it is not supported in Health Connect

* Remove more unsupported workout types

* Add missing import

* Remove Google Fit as dependency

* Add notice in README

* Improve logging for HC permission callback

* Update some documentation

* Android: Fix `requestAuthorization` not returning a result on success

* Remove additional workout types that are not supported

* Remove another workout type

* Add missing unimplemented method

* Implement sleep stage changes on iOS side

* Implement Android side

* Minor fix to README

* Add support for SLEEP_AWAKE_IN_BED

* Fix for [health 10.2.0] #1010
  • Loading branch information
SlimShadyIAm authored Aug 30, 2024
1 parent ce4d444 commit 2fb639d
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 107 deletions.
110 changes: 56 additions & 54 deletions packages/health/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ const val MEAL_UNKNOWN = "UNKNOWN"
const val NUTRITION = "NUTRITION"
const val SLEEP_ASLEEP = "SLEEP_ASLEEP"
const val SLEEP_AWAKE = "SLEEP_AWAKE"
const val SLEEP_AWAKE_IN_BED = "SLEEP_AWAKE_IN_BED"
const val SLEEP_DEEP = "SLEEP_DEEP"
const val SLEEP_IN_BED = "SLEEP_IN_BED"
const val SLEEP_LIGHT = "SLEEP_LIGHT"
const val SLEEP_OUT_OF_BED = "SLEEP_OUT_OF_BED"
const val SLEEP_REM = "SLEEP_REM"
const val SLEEP_SESSION = "SLEEP_SESSION"
const val SLEEP_UNKNOWN = "SLEEP_UNKNOWN"
const val SNACK = "SNACK"
const val WORKOUT = "WORKOUT"

Expand Down Expand Up @@ -1995,6 +1997,61 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
),
)

SLEEP_AWAKE_IN_BED ->
SleepSessionRecord(
startTime =
Instant.ofEpochMilli(
startTime
),
endTime =
Instant.ofEpochMilli(
endTime
),
startZoneOffset = null,
endZoneOffset = null,
stages =
listOf(
SleepSessionRecord
.Stage(
Instant.ofEpochMilli(
startTime
),
Instant.ofEpochMilli(
endTime
),
SleepSessionRecord
.STAGE_TYPE_AWAKE_IN_BED
)
),
)

SLEEP_UNKNOWN ->
SleepSessionRecord(
startTime =
Instant.ofEpochMilli(
startTime
),
endTime =
Instant.ofEpochMilli(
endTime
),
startZoneOffset = null,
endZoneOffset = null,
stages =
listOf(
SleepSessionRecord
.Stage(
Instant.ofEpochMilli(
startTime
),
Instant.ofEpochMilli(
endTime
),
SleepSessionRecord
.STAGE_TYPE_UNKNOWN
)
),
)
SLEEP_SESSION ->
SleepSessionRecord(
startTime =
Expand Down Expand Up @@ -2304,12 +2361,14 @@ class HealthPlugin(private var channel: MethodChannel? = null) :

private val mapSleepStageToType =
hashMapOf(
0 to SLEEP_UNKNOWN,
1 to SLEEP_AWAKE,
2 to SLEEP_ASLEEP,
3 to SLEEP_OUT_OF_BED,
4 to SLEEP_LIGHT,
5 to SLEEP_DEEP,
6 to SLEEP_REM,
7 to SLEEP_AWAKE_IN_BED
)

private val mapMealTypeToType =
Expand Down Expand Up @@ -2351,11 +2410,13 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
WATER to HydrationRecord::class,
SLEEP_ASLEEP to SleepSessionRecord::class,
SLEEP_AWAKE to SleepSessionRecord::class,
SLEEP_AWAKE_IN_BED to SleepSessionRecord::class,
SLEEP_LIGHT to SleepSessionRecord::class,
SLEEP_DEEP to SleepSessionRecord::class,
SLEEP_REM to SleepSessionRecord::class,
SLEEP_OUT_OF_BED to SleepSessionRecord::class,
SLEEP_SESSION to SleepSessionRecord::class,
SLEEP_UNKNOWN to SleepSessionRecord::class,
WORKOUT to ExerciseSessionRecord::class,
NUTRITION to NutritionRecord::class,
RESTING_HEART_RATE to RestingHeartRateRecord::class,
Expand Down
8 changes: 6 additions & 2 deletions packages/health/example/lib/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const List<HealthDataType> dataTypesIOS = [
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP,
HealthDataType.SLEEP_IN_BED,
HealthDataType.SLEEP_LIGHT,
HealthDataType.SLEEP_DEEP,
HealthDataType.SLEEP_REM,
HealthDataType.WATER,
Expand Down Expand Up @@ -81,11 +82,14 @@ const List<HealthDataType> dataTypesAndroid = [
HealthDataType.STEPS,
HealthDataType.DISTANCE_DELTA,
HealthDataType.RESPIRATORY_RATE,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP,
HealthDataType.SLEEP_LIGHT,
HealthDataType.SLEEP_AWAKE_IN_BED,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_DEEP,
HealthDataType.SLEEP_LIGHT,
HealthDataType.SLEEP_OUT_OF_BED,
HealthDataType.SLEEP_REM,
HealthDataType.SLEEP_UNKNOWN,
HealthDataType.SLEEP_SESSION,
HealthDataType.WATER,
HealthDataType.WORKOUT,
Expand Down
26 changes: 8 additions & 18 deletions packages/health/ios/Classes/SwiftHealthPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,11 @@ public class SwiftHealthPlugin: NSObject, FlutterPlugin {
let DISTANCE_CYCLING = "DISTANCE_CYCLING"
let FLIGHTS_CLIMBED = "FLIGHTS_CLIMBED"
let MINDFULNESS = "MINDFULNESS"
let SLEEP_IN_BED = "SLEEP_IN_BED"
let SLEEP_ASLEEP = "SLEEP_ASLEEP"
let SLEEP_ASLEEP_CORE = "SLEEP_ASLEEP_CORE"
let SLEEP_ASLEEP_DEEP = "SLEEP_ASLEEP_DEEP"
let SLEEP_ASLEEP_REM = "SLEEP_ASLEEP_REM"
let SLEEP_AWAKE = "SLEEP_AWAKE"
let SLEEP_DEEP = "SLEEP_DEEP"
let SLEEP_IN_BED = "SLEEP_IN_BED"
let SLEEP_LIGHT = "SLEEP_LIGHT"
let SLEEP_REM = "SLEEP_REM"

let EXERCISE_TIME = "EXERCISE_TIME"
Expand Down Expand Up @@ -867,19 +865,13 @@ public class SwiftHealthPlugin: NSObject, FlutterPlugin {
if dataTypeKey == self.SLEEP_IN_BED {
samplesCategory = samplesCategory.filter { $0.value == 0 }
}
if dataTypeKey == self.SLEEP_ASLEEP_CORE {
samplesCategory = samplesCategory.filter { $0.value == 3 }
}
if dataTypeKey == self.SLEEP_ASLEEP_DEEP {
samplesCategory = samplesCategory.filter { $0.value == 4 }
}
if dataTypeKey == self.SLEEP_ASLEEP_REM {
samplesCategory = samplesCategory.filter { $0.value == 5 }
if dataTypeKey == self.SLEEP_ASLEEP {
samplesCategory = samplesCategory.filter { $0.value == 1 }
}
if dataTypeKey == self.SLEEP_AWAKE {
samplesCategory = samplesCategory.filter { $0.value == 2 }
}
if dataTypeKey == self.SLEEP_ASLEEP {
if dataTypeKey == self.SLEEP_LIGHT {
samplesCategory = samplesCategory.filter { $0.value == 3 }
}
if dataTypeKey == self.SLEEP_DEEP {
Expand Down Expand Up @@ -1483,14 +1475,12 @@ public class SwiftHealthPlugin: NSObject, FlutterPlugin {
dataTypesDict[DISTANCE_CYCLING] = HKSampleType.quantityType(forIdentifier: .distanceCycling)!
dataTypesDict[FLIGHTS_CLIMBED] = HKSampleType.quantityType(forIdentifier: .flightsClimbed)!
dataTypesDict[MINDFULNESS] = HKSampleType.categoryType(forIdentifier: .mindfulSession)!
dataTypesDict[SLEEP_IN_BED] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_ASLEEP] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_ASLEEP_CORE] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_ASLEEP_DEEP] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_ASLEEP_REM] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_AWAKE] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_DEEP] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_IN_BED] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_LIGHT] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_REM] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[SLEEP_ASLEEP] = HKSampleType.categoryType(forIdentifier: .sleepAnalysis)!
dataTypesDict[MENSTRUATION_FLOW] = HKSampleType.categoryType(forIdentifier: .menstrualFlow)!


Expand Down
11 changes: 5 additions & 6 deletions packages/health/lib/health.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/health/lib/src/health_data_point.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ class HealthDataPoint {
type == HealthDataType.HEADACHE_MILD ||
type == HealthDataType.HEADACHE_MODERATE ||
type == HealthDataType.HEADACHE_SEVERE ||
type == HealthDataType.SLEEP_IN_BED ||
type == HealthDataType.SLEEP_ASLEEP ||
type == HealthDataType.SLEEP_AWAKE ||
type == HealthDataType.SLEEP_AWAKE_IN_BED ||
type == HealthDataType.SLEEP_DEEP ||
type == HealthDataType.SLEEP_IN_BED ||
type == HealthDataType.SLEEP_LIGHT ||
type == HealthDataType.SLEEP_REM ||
type == HealthDataType.SLEEP_UNKNOWN ||
type == HealthDataType.SLEEP_OUT_OF_BED) {
value = _convertMinutes();
}
Expand Down
8 changes: 2 additions & 6 deletions packages/health/lib/src/health_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,7 @@ class Health {
type == HealthDataType.SLEEP_IN_BED ||
type == HealthDataType.SLEEP_DEEP ||
type == HealthDataType.SLEEP_REM ||
type == HealthDataType.SLEEP_ASLEEP_CORE ||
type == HealthDataType.SLEEP_ASLEEP_DEEP ||
type == HealthDataType.SLEEP_ASLEEP_REM ||
type == HealthDataType.SLEEP_LIGHT ||
type == HealthDataType.HEADACHE_NOT_PRESENT ||
type == HealthDataType.HEADACHE_MILD ||
type == HealthDataType.HEADACHE_MODERATE ||
Expand Down Expand Up @@ -1054,13 +1052,11 @@ class Health {
/// Assigns numbers to specific [HealthDataType]s.
int _alignValue(HealthDataType type) => switch (type) {
HealthDataType.SLEEP_IN_BED => 0,
HealthDataType.SLEEP_ASLEEP => 1,
HealthDataType.SLEEP_AWAKE => 2,
HealthDataType.SLEEP_ASLEEP => 3,
HealthDataType.SLEEP_DEEP => 4,
HealthDataType.SLEEP_REM => 5,
HealthDataType.SLEEP_ASLEEP_CORE => 3,
HealthDataType.SLEEP_ASLEEP_DEEP => 4,
HealthDataType.SLEEP_ASLEEP_REM => 5,
HealthDataType.HEADACHE_UNSPECIFIED => 0,
HealthDataType.HEADACHE_NOT_PRESENT => 1,
HealthDataType.HEADACHE_MILD => 2,
Expand Down
37 changes: 17 additions & 20 deletions packages/health/lib/src/heath_data_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,16 @@ enum HealthDataType {
DISTANCE_DELTA,
MINDFULNESS,
WATER,
SLEEP_IN_BED,
SLEEP_ASLEEP,
SLEEP_ASLEEP_CORE,
SLEEP_ASLEEP_DEEP,
SLEEP_ASLEEP_REM,
SLEEP_AWAKE_IN_BED,
SLEEP_AWAKE,
SLEEP_LIGHT,
SLEEP_DEEP,
SLEEP_REM,
SLEEP_IN_BED,
SLEEP_LIGHT,
SLEEP_OUT_OF_BED,
SLEEP_REM,
SLEEP_SESSION,
SLEEP_UNKNOWN,
EXERCISE_TIME,
WORKOUT,
HEADACHE_NOT_PRESENT,
Expand Down Expand Up @@ -185,14 +184,12 @@ const List<HealthDataType> dataTypeKeysIOS = [
HealthDataType.DISTANCE_SWIMMING,
HealthDataType.DISTANCE_CYCLING,
HealthDataType.MINDFULNESS,
HealthDataType.SLEEP_IN_BED,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_DEEP,
HealthDataType.SLEEP_IN_BED,
HealthDataType.SLEEP_LIGHT,
HealthDataType.SLEEP_REM,
HealthDataType.SLEEP_ASLEEP_CORE,
HealthDataType.SLEEP_ASLEEP_DEEP,
HealthDataType.SLEEP_ASLEEP_REM,
HealthDataType.WATER,
HealthDataType.EXERCISE_TIME,
HealthDataType.WORKOUT,
Expand Down Expand Up @@ -226,14 +223,15 @@ const List<HealthDataType> dataTypeKeysAndroid = [
HealthDataType.STEPS,
HealthDataType.WEIGHT,
HealthDataType.DISTANCE_DELTA,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP,
HealthDataType.SLEEP_IN_BED,
HealthDataType.SLEEP_AWAKE_IN_BED,
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_DEEP,
HealthDataType.SLEEP_LIGHT,
HealthDataType.SLEEP_REM,
HealthDataType.SLEEP_OUT_OF_BED,
HealthDataType.SLEEP_REM,
HealthDataType.SLEEP_SESSION,
HealthDataType.SLEEP_UNKNOWN,
HealthDataType.WATER,
HealthDataType.WORKOUT,
HealthDataType.RESTING_HEART_RATE,
Expand Down Expand Up @@ -316,17 +314,16 @@ const Map<HealthDataType, HealthDataUnit> dataTypeToUnit = {
HealthDataType.DISTANCE_DELTA: HealthDataUnit.METER,

HealthDataType.WATER: HealthDataUnit.LITER,
HealthDataType.SLEEP_IN_BED: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_ASLEEP: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_ASLEEP_CORE: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_ASLEEP_DEEP: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_ASLEEP_REM: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_AWAKE: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_AWAKE_IN_BED: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_DEEP: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_REM: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_OUT_OF_BED: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_IN_BED: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_LIGHT: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_OUT_OF_BED: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_REM: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_SESSION: HealthDataUnit.MINUTE,
HealthDataType.SLEEP_UNKNOWN: HealthDataUnit.MINUTE,

HealthDataType.MINDFULNESS: HealthDataUnit.MINUTE,
HealthDataType.EXERCISE_TIME: HealthDataUnit.MINUTE,
Expand Down

0 comments on commit 2fb639d

Please sign in to comment.