1 /** 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * ``` 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * ``` 10 * 11 * Unless required by applicable law or agreed to in writing, software distributed under the License 12 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 13 * or implied. See the License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package com.android.healthconnect.testapps.toolbox.utils 17 18 import android.content.Context 19 import android.health.connect.datatypes.ActiveCaloriesBurnedRecord 20 import android.health.connect.datatypes.ActivityIntensityRecord 21 import android.health.connect.datatypes.BasalBodyTemperatureRecord 22 import android.health.connect.datatypes.BasalMetabolicRateRecord 23 import android.health.connect.datatypes.BloodGlucoseRecord 24 import android.health.connect.datatypes.BloodPressureRecord 25 import android.health.connect.datatypes.BodyFatRecord 26 import android.health.connect.datatypes.BodyTemperatureRecord 27 import android.health.connect.datatypes.BodyWaterMassRecord 28 import android.health.connect.datatypes.BoneMassRecord 29 import android.health.connect.datatypes.CervicalMucusRecord 30 import android.health.connect.datatypes.CyclingPedalingCadenceRecord 31 import android.health.connect.datatypes.CyclingPedalingCadenceRecord.CyclingPedalingCadenceRecordSample 32 import android.health.connect.datatypes.DistanceRecord 33 import android.health.connect.datatypes.ElevationGainedRecord 34 import android.health.connect.datatypes.ExerciseLap 35 import android.health.connect.datatypes.ExerciseSegment 36 import android.health.connect.datatypes.ExerciseSessionRecord 37 import android.health.connect.datatypes.FloorsClimbedRecord 38 import android.health.connect.datatypes.HeartRateRecord 39 import android.health.connect.datatypes.HeartRateRecord.HeartRateSample 40 import android.health.connect.datatypes.HeartRateVariabilityRmssdRecord 41 import android.health.connect.datatypes.HeightRecord 42 import android.health.connect.datatypes.HydrationRecord 43 import android.health.connect.datatypes.IntermenstrualBleedingRecord 44 import android.health.connect.datatypes.LeanBodyMassRecord 45 import android.health.connect.datatypes.MenstruationFlowRecord 46 import android.health.connect.datatypes.MenstruationPeriodRecord 47 import android.health.connect.datatypes.Metadata 48 import android.health.connect.datatypes.MindfulnessSessionRecord 49 import android.health.connect.datatypes.NutritionRecord 50 import android.health.connect.datatypes.OvulationTestRecord 51 import android.health.connect.datatypes.OxygenSaturationRecord 52 import android.health.connect.datatypes.PlannedExerciseBlock 53 import android.health.connect.datatypes.PlannedExerciseSessionRecord 54 import android.health.connect.datatypes.PowerRecord 55 import android.health.connect.datatypes.PowerRecord.PowerRecordSample 56 import android.health.connect.datatypes.Record 57 import android.health.connect.datatypes.RespiratoryRateRecord 58 import android.health.connect.datatypes.RestingHeartRateRecord 59 import android.health.connect.datatypes.SexualActivityRecord 60 import android.health.connect.datatypes.SkinTemperatureRecord 61 import android.health.connect.datatypes.SleepSessionRecord 62 import android.health.connect.datatypes.SpeedRecord 63 import android.health.connect.datatypes.SpeedRecord.SpeedRecordSample 64 import android.health.connect.datatypes.StepsCadenceRecord 65 import android.health.connect.datatypes.StepsCadenceRecord.StepsCadenceRecordSample 66 import android.health.connect.datatypes.StepsRecord 67 import android.health.connect.datatypes.TotalCaloriesBurnedRecord 68 import android.health.connect.datatypes.Vo2MaxRecord 69 import android.health.connect.datatypes.WeightRecord 70 import android.health.connect.datatypes.WheelchairPushesRecord 71 import android.health.connect.datatypes.units.BloodGlucose 72 import android.health.connect.datatypes.units.Energy 73 import android.health.connect.datatypes.units.Length 74 import android.health.connect.datatypes.units.Mass 75 import android.health.connect.datatypes.units.Percentage 76 import android.health.connect.datatypes.units.Power 77 import android.health.connect.datatypes.units.Pressure 78 import android.health.connect.datatypes.units.Temperature 79 import android.health.connect.datatypes.units.Volume 80 import com.android.healthconnect.testapps.toolbox.data.ExerciseRoutesTestData 81 import com.android.healthconnect.testapps.toolbox.data.ExerciseRoutesTestData.Companion.generateExerciseRouteFromLocations 82 import com.android.healthconnect.testapps.toolbox.fieldviews.InputFieldView 83 import com.android.healthconnect.testapps.toolbox.utils.GeneralUtils.Companion.getMetaData 84 import java.time.Instant 85 import kotlin.reflect.KClass 86 87 class InsertOrUpdateRecords { 88 89 companion object { 90 getStringValuenull91 private fun getStringValue( 92 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 93 fieldName: String, 94 ): String { 95 return mFieldNameToFieldInput[fieldName]?.getFieldValue().toString() 96 } 97 getIntegerValuenull98 private fun getIntegerValue( 99 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 100 fieldName: String, 101 ): Int { 102 return getStringValue(mFieldNameToFieldInput, fieldName).toInt() 103 } 104 getLongValuenull105 private fun getLongValue( 106 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 107 fieldName: String, 108 ): Long { 109 return getStringValue(mFieldNameToFieldInput, fieldName).toLong() 110 } 111 getDoubleValuenull112 private fun getDoubleValue( 113 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 114 fieldName: String, 115 ): Double { 116 return getStringValue(mFieldNameToFieldInput, fieldName).toDouble() 117 } 118 getStartTimenull119 private fun getStartTime(mFieldNameToFieldInput: HashMap<String, InputFieldView>): Instant { 120 return mFieldNameToFieldInput["startTime"]?.getFieldValue() as Instant 121 } 122 getEndTimenull123 private fun getEndTime(mFieldNameToFieldInput: HashMap<String, InputFieldView>): Instant { 124 return mFieldNameToFieldInput["endTime"]?.getFieldValue() as Instant 125 } 126 getTimenull127 private fun getTime(mFieldNameToFieldInput: HashMap<String, InputFieldView>): Instant { 128 return mFieldNameToFieldInput["time"]?.getFieldValue() as Instant 129 } 130 getMassnull131 private fun getMass( 132 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 133 fieldName: String, 134 ): Mass { 135 return Mass.fromGrams(getDoubleValue(mFieldNameToFieldInput, fieldName)) 136 } 137 getTemperaturenull138 private fun getTemperature( 139 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 140 fieldName: String, 141 ): Temperature { 142 return Temperature.fromCelsius(getDoubleValue(mFieldNameToFieldInput, fieldName)) 143 } 144 createRecordObjectnull145 fun createRecordObject( 146 recordClass: KClass<out Record>, 147 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 148 context: Context, 149 recordUuid: String, 150 ): Record { 151 return createRecordObjectHelper( 152 recordClass, 153 mFieldNameToFieldInput, 154 getMetaData(context, recordUuid), 155 ) 156 } 157 createRecordObjectnull158 fun createRecordObject( 159 recordClass: KClass<out Record>, 160 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 161 context: Context, 162 ): Record { 163 return createRecordObjectHelper( 164 recordClass, 165 mFieldNameToFieldInput, 166 getMetaData(context), 167 ) 168 } 169 createRecordObjectHelpernull170 private fun createRecordObjectHelper( 171 recordClass: KClass<out Record>, 172 mFieldNameToFieldInput: HashMap<String, InputFieldView>, 173 metaData: Metadata, 174 ): Record { 175 return when (recordClass) { 176 StepsRecord::class -> 177 StepsRecord.Builder( 178 metaData, 179 getStartTime(mFieldNameToFieldInput), 180 getEndTime(mFieldNameToFieldInput), 181 getLongValue(mFieldNameToFieldInput, "mCount"), 182 ) 183 .build() 184 185 DistanceRecord::class -> 186 DistanceRecord.Builder( 187 metaData, 188 getStartTime(mFieldNameToFieldInput), 189 getEndTime(mFieldNameToFieldInput), 190 Length.fromMeters(getDoubleValue(mFieldNameToFieldInput, "mDistance")), 191 ) 192 .build() 193 194 ActiveCaloriesBurnedRecord::class -> 195 ActiveCaloriesBurnedRecord.Builder( 196 metaData, 197 getStartTime(mFieldNameToFieldInput), 198 getEndTime(mFieldNameToFieldInput), 199 Energy.fromCalories(getDoubleValue(mFieldNameToFieldInput, "mEnergy")), 200 ) 201 .build() 202 203 ElevationGainedRecord::class -> 204 ElevationGainedRecord.Builder( 205 metaData, 206 getStartTime(mFieldNameToFieldInput), 207 getEndTime(mFieldNameToFieldInput), 208 Length.fromMeters(getDoubleValue(mFieldNameToFieldInput, "mElevation")), 209 ) 210 .build() 211 212 BasalMetabolicRateRecord::class -> 213 BasalMetabolicRateRecord.Builder( 214 metaData, 215 getTime(mFieldNameToFieldInput), 216 Power.fromWatts( 217 getDoubleValue(mFieldNameToFieldInput, "mBasalMetabolicRate") 218 ), 219 ) 220 .build() 221 222 SpeedRecord::class -> 223 SpeedRecord.Builder( 224 metaData, 225 getStartTime(mFieldNameToFieldInput), 226 getEndTime(mFieldNameToFieldInput), 227 mFieldNameToFieldInput["mSpeedRecordSamples"]?.getFieldValue() 228 as List<SpeedRecordSample>, 229 ) 230 .build() 231 232 HeartRateRecord::class -> 233 HeartRateRecord.Builder( 234 metaData, 235 getStartTime(mFieldNameToFieldInput), 236 getEndTime(mFieldNameToFieldInput), 237 mFieldNameToFieldInput["mHeartRateSamples"]?.getFieldValue() 238 as List<HeartRateSample>, 239 ) 240 .build() 241 242 PowerRecord::class -> 243 PowerRecord.Builder( 244 metaData, 245 getStartTime(mFieldNameToFieldInput), 246 getEndTime(mFieldNameToFieldInput), 247 mFieldNameToFieldInput["mPowerRecordSamples"]?.getFieldValue() 248 as List<PowerRecordSample>, 249 ) 250 .build() 251 252 CyclingPedalingCadenceRecord::class -> 253 CyclingPedalingCadenceRecord.Builder( 254 metaData, 255 getStartTime(mFieldNameToFieldInput), 256 getEndTime(mFieldNameToFieldInput), 257 mFieldNameToFieldInput["mCyclingPedalingCadenceRecordSamples"] 258 ?.getFieldValue() as List<CyclingPedalingCadenceRecordSample>, 259 ) 260 .build() 261 262 FloorsClimbedRecord::class -> 263 FloorsClimbedRecord.Builder( 264 metaData, 265 getStartTime(mFieldNameToFieldInput), 266 getEndTime(mFieldNameToFieldInput), 267 getDoubleValue(mFieldNameToFieldInput, "mFloors"), 268 ) 269 .build() 270 271 TotalCaloriesBurnedRecord::class -> 272 TotalCaloriesBurnedRecord.Builder( 273 metaData, 274 getStartTime(mFieldNameToFieldInput), 275 getEndTime(mFieldNameToFieldInput), 276 Energy.fromCalories(getDoubleValue(mFieldNameToFieldInput, "mEnergy")), 277 ) 278 .build() 279 280 WheelchairPushesRecord::class -> 281 WheelchairPushesRecord.Builder( 282 metaData, 283 getStartTime(mFieldNameToFieldInput), 284 getEndTime(mFieldNameToFieldInput), 285 getLongValue(mFieldNameToFieldInput, "mCount"), 286 ) 287 .build() 288 289 Vo2MaxRecord::class -> 290 Vo2MaxRecord.Builder( 291 metaData, 292 getTime(mFieldNameToFieldInput), 293 getIntegerValue(mFieldNameToFieldInput, "mMeasurementMethod"), 294 getDoubleValue( 295 mFieldNameToFieldInput, 296 "mVo2MillilitersPerMinuteKilogram", 297 ), 298 ) 299 .build() 300 301 BodyFatRecord::class -> 302 BodyFatRecord.Builder( 303 metaData, 304 getTime(mFieldNameToFieldInput), 305 Percentage.fromValue( 306 getDoubleValue(mFieldNameToFieldInput, "mPercentage") 307 ), 308 ) 309 .build() 310 311 BodyWaterMassRecord::class -> 312 BodyWaterMassRecord.Builder( 313 metaData, 314 getTime(mFieldNameToFieldInput), 315 getMass(mFieldNameToFieldInput, "mBodyWaterMass"), 316 ) 317 .build() 318 319 BoneMassRecord::class -> 320 BoneMassRecord.Builder( 321 metaData, 322 getTime(mFieldNameToFieldInput), 323 getMass(mFieldNameToFieldInput, "mMass"), 324 ) 325 .build() 326 327 HeightRecord::class -> 328 HeightRecord.Builder( 329 metaData, 330 getTime(mFieldNameToFieldInput), 331 Length.fromMeters(getDoubleValue(mFieldNameToFieldInput, "mHeight")), 332 ) 333 .build() 334 335 LeanBodyMassRecord::class -> 336 LeanBodyMassRecord.Builder( 337 metaData, 338 getTime(mFieldNameToFieldInput), 339 getMass(mFieldNameToFieldInput, "mMass"), 340 ) 341 .build() 342 343 WeightRecord::class -> 344 WeightRecord.Builder( 345 metaData, 346 getTime(mFieldNameToFieldInput), 347 getMass(mFieldNameToFieldInput, "mWeight"), 348 ) 349 .build() 350 351 CervicalMucusRecord::class -> 352 CervicalMucusRecord.Builder( 353 metaData, 354 getTime(mFieldNameToFieldInput), 355 getIntegerValue(mFieldNameToFieldInput, "mSensation"), 356 getIntegerValue(mFieldNameToFieldInput, "mAppearance"), 357 ) 358 .build() 359 360 MenstruationFlowRecord::class -> 361 MenstruationFlowRecord.Builder( 362 metaData, 363 getTime(mFieldNameToFieldInput), 364 getIntegerValue(mFieldNameToFieldInput, "mFlow"), 365 ) 366 .build() 367 368 OvulationTestRecord::class -> 369 OvulationTestRecord.Builder( 370 metaData, 371 getTime(mFieldNameToFieldInput), 372 getIntegerValue(mFieldNameToFieldInput, "mResult"), 373 ) 374 .build() 375 376 SexualActivityRecord::class -> 377 SexualActivityRecord.Builder( 378 metaData, 379 getTime(mFieldNameToFieldInput), 380 getIntegerValue(mFieldNameToFieldInput, "mProtectionUsed"), 381 ) 382 .build() 383 384 HydrationRecord::class -> 385 HydrationRecord.Builder( 386 metaData, 387 getStartTime(mFieldNameToFieldInput), 388 getEndTime(mFieldNameToFieldInput), 389 Volume.fromLiters(getDoubleValue(mFieldNameToFieldInput, "mVolume")), 390 ) 391 .build() 392 393 IntermenstrualBleedingRecord::class -> 394 IntermenstrualBleedingRecord.Builder(metaData, getTime(mFieldNameToFieldInput)) 395 .build() 396 397 BasalBodyTemperatureRecord::class -> 398 BasalBodyTemperatureRecord.Builder( 399 metaData, 400 getTime(mFieldNameToFieldInput), 401 getIntegerValue( 402 mFieldNameToFieldInput, 403 "mBodyTemperatureMeasurementLocation", 404 ), 405 Temperature.fromCelsius( 406 getDoubleValue(mFieldNameToFieldInput, "mTemperature") 407 ), 408 ) 409 .build() 410 411 BloodGlucoseRecord::class -> 412 BloodGlucoseRecord.Builder( 413 metaData, 414 getTime(mFieldNameToFieldInput), 415 getIntegerValue(mFieldNameToFieldInput, "mSpecimenSource"), 416 BloodGlucose.fromMillimolesPerLiter( 417 getDoubleValue(mFieldNameToFieldInput, "mLevel") 418 ), 419 getIntegerValue(mFieldNameToFieldInput, "mRelationToMeal"), 420 getIntegerValue(mFieldNameToFieldInput, "mMealType"), 421 ) 422 .build() 423 424 BloodPressureRecord::class -> 425 BloodPressureRecord.Builder( 426 metaData, 427 getTime(mFieldNameToFieldInput), 428 getIntegerValue(mFieldNameToFieldInput, "mMeasurementLocation"), 429 Pressure.fromMillimetersOfMercury( 430 getDoubleValue(mFieldNameToFieldInput, "mSystolic") 431 ), 432 Pressure.fromMillimetersOfMercury( 433 getDoubleValue(mFieldNameToFieldInput, "mDiastolic") 434 ), 435 getIntegerValue(mFieldNameToFieldInput, "mBodyPosition"), 436 ) 437 .build() 438 439 BodyTemperatureRecord::class -> 440 BodyTemperatureRecord.Builder( 441 metaData, 442 getTime(mFieldNameToFieldInput), 443 getIntegerValue(mFieldNameToFieldInput, "mMeasurementLocation"), 444 Temperature.fromCelsius( 445 getDoubleValue(mFieldNameToFieldInput, "mTemperature") 446 ), 447 ) 448 .build() 449 450 HeartRateVariabilityRmssdRecord::class -> 451 HeartRateVariabilityRmssdRecord.Builder( 452 metaData, 453 getTime(mFieldNameToFieldInput), 454 getDoubleValue(mFieldNameToFieldInput, "mHeartRateVariabilityMillis"), 455 ) 456 .build() 457 458 OxygenSaturationRecord::class -> 459 OxygenSaturationRecord.Builder( 460 metaData, 461 getTime(mFieldNameToFieldInput), 462 Percentage.fromValue( 463 getDoubleValue(mFieldNameToFieldInput, "mPercentage") 464 ), 465 ) 466 .build() 467 468 RespiratoryRateRecord::class -> 469 RespiratoryRateRecord.Builder( 470 metaData, 471 getTime(mFieldNameToFieldInput), 472 getDoubleValue(mFieldNameToFieldInput, "mRate"), 473 ) 474 .build() 475 476 RestingHeartRateRecord::class -> 477 RestingHeartRateRecord.Builder( 478 metaData, 479 getTime(mFieldNameToFieldInput), 480 getLongValue(mFieldNameToFieldInput, "mBeatsPerMinute"), 481 ) 482 .build() 483 484 SkinTemperatureRecord::class -> 485 SkinTemperatureRecord.Builder( 486 metaData, 487 getStartTime(mFieldNameToFieldInput), 488 getEndTime(mFieldNameToFieldInput), 489 ) 490 .apply { 491 OxygenSaturationRecord.Builder( 492 metaData, 493 getTime(mFieldNameToFieldInput), 494 Percentage.fromValue( 495 getDoubleValue(mFieldNameToFieldInput, "mPercentage") 496 ), 497 ) 498 .build() 499 if (!mFieldNameToFieldInput["mDeltas"]!!.isEmpty()) { 500 setDeltas( 501 mFieldNameToFieldInput["mDeltas"]?.getFieldValue() 502 as List<SkinTemperatureRecord.Delta> 503 ) 504 } 505 if (!mFieldNameToFieldInput["mBaseline"]!!.isEmpty()) { 506 setBaseline(getTemperature(mFieldNameToFieldInput, "mBaseline")) 507 } 508 if (!mFieldNameToFieldInput["mMeasurementLocation"]!!.isEmpty()) { 509 setMeasurementLocation( 510 getIntegerValue(mFieldNameToFieldInput, "mMeasurementLocation") 511 ) 512 } 513 } 514 .build() 515 516 SleepSessionRecord::class -> 517 SleepSessionRecord.Builder( 518 metaData, 519 getStartTime(mFieldNameToFieldInput), 520 getEndTime(mFieldNameToFieldInput), 521 ) 522 .apply { 523 if (!mFieldNameToFieldInput["mNotes"]!!.isEmpty()) { 524 setNotes(getStringValue(mFieldNameToFieldInput, "mNotes")) 525 } 526 if (!mFieldNameToFieldInput["mTitle"]!!.isEmpty()) { 527 setTitle(getStringValue(mFieldNameToFieldInput, "mTitle")) 528 } 529 if (!mFieldNameToFieldInput["mStages"]!!.isEmpty()) { 530 setStages( 531 mFieldNameToFieldInput["mStages"]?.getFieldValue() 532 as List<SleepSessionRecord.Stage> 533 ) 534 } 535 } 536 .build() 537 538 StepsCadenceRecord::class -> 539 StepsCadenceRecord.Builder( 540 metaData, 541 getStartTime(mFieldNameToFieldInput), 542 getEndTime(mFieldNameToFieldInput), 543 mFieldNameToFieldInput["mStepsCadenceRecordSamples"]?.getFieldValue() 544 as List<StepsCadenceRecordSample>, 545 ) 546 .build() 547 548 MenstruationPeriodRecord::class -> 549 MenstruationPeriodRecord.Builder( 550 metaData, 551 getStartTime(mFieldNameToFieldInput), 552 getEndTime(mFieldNameToFieldInput), 553 ) 554 .build() 555 556 ExerciseSessionRecord::class -> { 557 val startTime = mFieldNameToFieldInput["startTime"]?.getFieldValue() as Instant 558 559 ExerciseSessionRecord.Builder( 560 metaData, 561 startTime, 562 mFieldNameToFieldInput["endTime"]?.getFieldValue() as Instant, 563 mFieldNameToFieldInput["mExerciseType"] 564 ?.getFieldValue() 565 .toString() 566 .toInt(), 567 ) 568 .apply { 569 if (!mFieldNameToFieldInput["mNotes"]!!.isEmpty()) { 570 setNotes(getStringValue(mFieldNameToFieldInput, "mNotes")) 571 } 572 if (!mFieldNameToFieldInput["mTitle"]!!.isEmpty()) { 573 setTitle(getStringValue(mFieldNameToFieldInput, "mTitle")) 574 } 575 if (!mFieldNameToFieldInput["mExerciseRoute"]!!.isEmpty()) { 576 val exerciseRoutes = 577 mFieldNameToFieldInput["mExerciseRoute"]?.getFieldValue() 578 as List<ExerciseRoutesTestData.ExerciseRouteLocationData> 579 setRoute( 580 generateExerciseRouteFromLocations( 581 exerciseRoutes, 582 startTime.toEpochMilli(), 583 ) 584 ) 585 } 586 if (!mFieldNameToFieldInput["mSegments"]!!.isEmpty()) { 587 setSegments( 588 mFieldNameToFieldInput["mSegments"]?.getFieldValue() 589 as List<ExerciseSegment> 590 ) 591 } 592 if (!mFieldNameToFieldInput["mLaps"]!!.isEmpty()) { 593 setLaps( 594 mFieldNameToFieldInput["mLaps"]?.getFieldValue() 595 as List<ExerciseLap> 596 ) 597 } 598 } 599 .build() 600 } 601 602 PlannedExerciseSessionRecord::class -> { 603 val startTime = mFieldNameToFieldInput["startTime"]?.getFieldValue() as Instant 604 PlannedExerciseSessionRecord.Builder( 605 metaData, 606 mFieldNameToFieldInput["mPlannedExerciseType"] 607 ?.getFieldValue() 608 .toString() 609 .toInt(), 610 startTime, 611 mFieldNameToFieldInput["endTime"]?.getFieldValue() as Instant, 612 ) 613 .apply { 614 if (!mFieldNameToFieldInput["mNotes"]!!.isEmpty()) { 615 setNotes(getStringValue(mFieldNameToFieldInput, "mNotes")) 616 } 617 if (!mFieldNameToFieldInput["mTitle"]!!.isEmpty()) { 618 setTitle(getStringValue(mFieldNameToFieldInput, "mTitle")) 619 } 620 if (!mFieldNameToFieldInput["mBlocks"]!!.isEmpty()) { 621 setBlocks( 622 mFieldNameToFieldInput["mBlocks"]?.getFieldValue() 623 as List<PlannedExerciseBlock> 624 ) 625 } 626 } 627 .build() 628 } 629 630 NutritionRecord::class -> 631 NutritionRecord.Builder( 632 metaData, 633 getStartTime(mFieldNameToFieldInput), 634 getEndTime(mFieldNameToFieldInput), 635 ) 636 .apply { 637 if (!mFieldNameToFieldInput["mBiotin"]!!.isEmpty()) { 638 setBiotin(getMass(mFieldNameToFieldInput, "mBiotin")) 639 } 640 if (!mFieldNameToFieldInput["mCaffeine"]!!.isEmpty()) { 641 setCaffeine(getMass(mFieldNameToFieldInput, "mCaffeine")) 642 } 643 if (!mFieldNameToFieldInput["mCalcium"]!!.isEmpty()) { 644 setCalcium(getMass(mFieldNameToFieldInput, "mCalcium")) 645 } 646 if (!mFieldNameToFieldInput["mChloride"]!!.isEmpty()) { 647 setChloride(getMass(mFieldNameToFieldInput, "mChloride")) 648 } 649 if (!mFieldNameToFieldInput["mCholesterol"]!!.isEmpty()) { 650 setCholesterol(getMass(mFieldNameToFieldInput, "mCholesterol")) 651 } 652 if (!mFieldNameToFieldInput["mChromium"]!!.isEmpty()) { 653 setChromium(getMass(mFieldNameToFieldInput, "mChromium")) 654 } 655 if (!mFieldNameToFieldInput["mDietaryFiber"]!!.isEmpty()) { 656 setDietaryFiber(getMass(mFieldNameToFieldInput, "mDietaryFiber")) 657 } 658 if (!mFieldNameToFieldInput["mCopper"]!!.isEmpty()) { 659 setCopper(getMass(mFieldNameToFieldInput, "mCopper")) 660 } 661 if (!mFieldNameToFieldInput["mEnergy"]!!.isEmpty()) { 662 setEnergy( 663 Energy.fromCalories( 664 getDoubleValue(mFieldNameToFieldInput, "mEnergy") 665 ) 666 ) 667 } 668 if (!mFieldNameToFieldInput["mFolate"]!!.isEmpty()) { 669 setFolate(getMass(mFieldNameToFieldInput, "mFolate")) 670 } 671 if (!mFieldNameToFieldInput["mEnergyFromFat"]!!.isEmpty()) { 672 setEnergyFromFat( 673 Energy.fromCalories( 674 getDoubleValue(mFieldNameToFieldInput, "mEnergyFromFat") 675 ) 676 ) 677 } 678 if (!mFieldNameToFieldInput["mFolicAcid"]!!.isEmpty()) { 679 setFolicAcid(getMass(mFieldNameToFieldInput, "mFolicAcid")) 680 } 681 if (!mFieldNameToFieldInput["mIodine"]!!.isEmpty()) { 682 setIodine(getMass(mFieldNameToFieldInput, "mIodine")) 683 } 684 if (!mFieldNameToFieldInput["mIron"]!!.isEmpty()) { 685 setIron(getMass(mFieldNameToFieldInput, "mIron")) 686 } 687 if (!mFieldNameToFieldInput["mMagnesium"]!!.isEmpty()) { 688 setMagnesium(getMass(mFieldNameToFieldInput, "mMagnesium")) 689 } 690 if (!mFieldNameToFieldInput["mManganese"]!!.isEmpty()) { 691 setManganese(getMass(mFieldNameToFieldInput, "mManganese")) 692 } 693 } 694 .build() 695 696 MindfulnessSessionRecord::class -> 697 MindfulnessSessionRecord.Builder( 698 metaData, 699 getStartTime(mFieldNameToFieldInput), 700 getEndTime(mFieldNameToFieldInput), 701 mFieldNameToFieldInput["mMindfulnessSessionType"] 702 ?.getFieldValue() 703 .toString() 704 .toInt(), 705 ) 706 .apply { 707 mFieldNameToFieldInput["mTitle"] 708 ?.takeIf { !it.isEmpty() } 709 ?.let { setTitle(it.getFieldValue().toString()) } 710 mFieldNameToFieldInput["mNotes"] 711 ?.takeIf { !it.isEmpty() } 712 ?.let { setNotes(it.getFieldValue().toString()) } 713 } 714 .build() 715 716 ActivityIntensityRecord::class -> 717 ActivityIntensityRecord.Builder( 718 metaData, 719 getStartTime(mFieldNameToFieldInput), 720 getEndTime(mFieldNameToFieldInput), 721 mFieldNameToFieldInput["mActivityIntensityType"] 722 ?.getFieldValue() 723 .toString() 724 .toInt(), 725 ) 726 .build() 727 728 else -> throw NotImplementedError("Record type not implemented") 729 } 730 } 731 } 732 } 733