samsung integration addded

watch_integration
tahaalam 1 month ago
parent df0b926e59
commit 5ea70397e2

@ -28,7 +28,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.time.Duration
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.LocalTime import java.time.LocalTime
@ -75,6 +74,8 @@ class SamsungWatch(
Permission.of(DataTypes.BLOOD_OXYGEN, AccessType.READ), Permission.of(DataTypes.BLOOD_OXYGEN, AccessType.READ),
Permission.of(DataTypes.ACTIVITY_SUMMARY, AccessType.READ), Permission.of(DataTypes.ACTIVITY_SUMMARY, AccessType.READ),
Permission.of(DataTypes.SLEEP, AccessType.READ), Permission.of(DataTypes.SLEEP, AccessType.READ),
Permission.of(DataTypes.BLOOD_OXYGEN, AccessType.READ),
Permission.of(DataTypes.BODY_TEMPERATURE, AccessType.READ),
// Permission.of(DataTypes.SKIN_TEMPERATURE, AccessType.READ), // Permission.of(DataTypes.SKIN_TEMPERATURE, AccessType.READ),
// Permission.of(DataTypes.NUTRITION, AccessType.READ), // Permission.of(DataTypes.NUTRITION, AccessType.READ),
@ -115,7 +116,7 @@ class SamsungWatch(
processHeartVital(heartRateList) processHeartVital(heartRateList)
Log.d("TAG"," the data is ${vitals}") Log.d("TAG"," the data is ${vitals}")
print("the data is ${vitals}") print("the data is ${vitals}")
result.success("Permission Granted") result.success("Data is obtained")
} }
} }
@ -132,7 +133,7 @@ class SamsungWatch(
processSleepVital(sleepData) processSleepVital(sleepData)
print("the data is $vitals") print("the data is $vitals")
Log.d(TAG, "the data is $vitals") Log.d(TAG, "the data is $vitals")
result.success("Permission Granted") result.success("Data is obtained")
} }
} }
@ -151,10 +152,80 @@ class SamsungWatch(
processStepsCount(steps) processStepsCount(steps)
print("the data is $vitals") print("the data is $vitals")
Log.d(TAG, "the data is $vitals") Log.d(TAG, "the data is $vitals")
result.success("Permission Granted") result.success("Data is obtained")
} }
} }
"activitySummary"->{
val dateTime = LocalDateTime.now().with(LocalTime.MIDNIGHT).minusDays(365)
val localTimeFilter = LocalTimeFilter.of(dateTime, LocalDateTime.now())
val localTimeGroup = LocalTimeGroup.of(LocalTimeGroupUnit.HOURLY, 1)
val readRequest = DataType.ActivitySummaryType.TOTAL_CALORIES_BURNED.requestBuilder
.setLocalTimeFilterWithGroup(localTimeFilter, localTimeGroup)
.setOrdering(Ordering.DESC)
.build()
scope.launch {
val activityResult = dataStore.aggregateData(readRequest).dataList
processActivity(activityResult)
Log.d("TAG"," the data is ${vitals}")
print("the data is ${vitals}")
result.success("Data is obtained")
}
}
"bloodOxygen"->{
val dateTime = LocalDateTime.now().with(LocalTime.MIDNIGHT).minusDays(365)
val localTimeFilter = LocalTimeFilter.of(dateTime, LocalDateTime.now())
val readRequest = DataTypes.BLOOD_OXYGEN.readDataRequestBuilder
.setLocalTimeFilter(localTimeFilter)
.setOrdering(Ordering.DESC)
.build()
scope.launch {
val bloodOxygenList = dataStore.readData(readRequest).dataList
processBloodOxygen(bloodOxygenList)
Log.d("TAG"," the data is ${vitals}")
print("the data is ${vitals["bloodOxygen"]}")
result.success("Data is obtained")
}
}
"bodyTemperature"->{
val dateTime = LocalDateTime.now().with(LocalTime.MIDNIGHT).minusDays(365)
val localTimeFilter = LocalTimeFilter.of(dateTime, LocalDateTime.now())
val readRequest = DataTypes.BODY_TEMPERATURE.readDataRequestBuilder
.setLocalTimeFilter(localTimeFilter)
.setOrdering(Ordering.DESC)
.build()
scope.launch {
val bodyTemperatureList = dataStore.readData(readRequest).dataList
processBodyTemperature(bodyTemperatureList)
Log.d("TAG"," the data is ${vitals}")
print("the data is ${vitals["bodyTemperature"]}")
result.success("Data is obtained")
}
}
"retrieveData"->{
if(vitals.isEmpty()){
result.error("NoDataFound", "No Data was obtained", null)
return@setMethodCallHandler
}
result.success("""
{
"heartRate": ${vitals["heartRate"]},
"steps": ${vitals["steps"]},
"sleep": ${vitals["sleep"]},
"activity": ${vitals["activity"]},
"bloodOxygen": ${vitals["bloodOxygen"]},
"bodyTemperature": ${vitals["bodyTemperature"]}
}
""".trimIndent())
}
"closeCoroutineScope"->{ "closeCoroutineScope"->{
destroy() destroy()
@ -168,16 +239,51 @@ class SamsungWatch(
} }
} }
private fun CoroutineScope.processBodyTemperature( bodyTemperatureList :List<HealthDataPoint>) {
vitals["bodyTemperature"] = mutableListOf()
bodyTemperatureList.forEach { stepData ->
val vitalData = Vitals().apply {
value = stepData.getValue(DataType.BodyTemperatureType.BODY_TEMPERATURE).toString()
timeStamp = stepData.endTime.toString()
}
(vitals["bodyTemperature"] as MutableList).add(vitalData)
}
}
private fun CoroutineScope.processBloodOxygen( bloodOxygenList :List<HealthDataPoint>) {
vitals["bloodOxygen"] = mutableListOf()
bloodOxygenList.forEach { stepData ->
val vitalData = Vitals().apply {
value = stepData.getValue(DataType.BloodOxygenType.OXYGEN_SATURATION).toString()
timeStamp = stepData.endTime.toString()
}
(vitals["bloodOxygen"] as MutableList).add(vitalData)
}
}
private fun CoroutineScope.processActivity(activityResult: List<AggregatedData<Float>>) {
vitals["activity"] = mutableListOf()
activityResult.forEach { stepData ->
val vitalData = Vitals().apply {
value = stepData.value.toString()
timeStamp = stepData.endTime.toString()
}
(vitals["activity"] as MutableList).add(vitalData)
}
}
private fun CoroutineScope.processStepsCount(result: DataResponse<AggregatedData<Long>>) { private fun CoroutineScope.processStepsCount(result: DataResponse<AggregatedData<Long>>) {
val stepCount = ArrayList<AggregatedData<Long>>() val stepCount = ArrayList<AggregatedData<Long>>()
var totalSteps: Long = 0 var totalSteps: Long = 0
vitals["steps"] = emptyList() vitals["steps"] = mutableListOf()
result.dataList.forEach { stepData -> result.dataList.forEach { stepData ->
val vitalData = Vitals().apply { val vitalData = Vitals().apply {
value = (stepData.value as Long).toString() value = (stepData.value as Long).toString()
timeStamp = stepData.startTime.toString() timeStamp = stepData.startTime.toString()
} }
(vitals["sleep"] as MutableList).add(vitalData) (vitals["steps"] as MutableList).add(vitalData)
} }
} }

@ -2,5 +2,12 @@ package com.ejada.hmg.samsung_watch.model
data class Vitals( data class Vitals(
var value : String = "", var value : String = "",
var timeStamp : String = "" var timeStamp :String = ""
) ){
override fun toString(): String {
return """{
"value": "$value",
"timeStamp": "$timeStamp"}
""".trimIndent()
}
}

File diff suppressed because one or more lines are too long

@ -109,17 +109,17 @@ class HealthProvider with ChangeNotifier {
if (result.isError) { if (result.isError) {
error = 'Error initializing device: ${result.asError}'; error = 'Error initializing device: ${result.asError}';
} else { } else {
getHeartRate(); getVitals();
getIt.get<NavigationService>().pushPage(page: SmartWatchActivity()); getIt.get<NavigationService>().pushPage(page: SmartWatchActivity());
print('Device initialized successfully'); print('Device initialized successfully');
} }
notifyListeners(); notifyListeners();
} }
void getHeartRate() async{ void getVitals() async{
isLoading = true; isLoading = true;
notifyListeners(); notifyListeners();
final result = await _healthService.getHeartRate(); final result = await _healthService.getVitals();
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
} }

@ -1,8 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:health/health.dart'; import 'package:health/health.dart';
import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart'; import 'package:hmg_patient_app_new/core/common_models/smart_watch.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/model/Vitals.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/create_watch_helper.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/create_watch_helper.dart';
import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart'; import 'package:hmg_patient_app_new/features/smartwatch_health_data/watch_connectors/watch_helper.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -180,7 +183,7 @@ class HealthService {
return await watchHelper!.initDevice(); return await watchHelper!.initDevice();
} }
FutureOr<void> getHeartRate() async { FutureOr<void> getVitals() async {
if (watchHelper == null) { if (watchHelper == null) {
print('No watch helper found'); print('No watch helper found');
return; return;
@ -189,6 +192,19 @@ class HealthService {
await watchHelper!.getHeartRate(); await watchHelper!.getHeartRate();
await watchHelper!.getSleep(); await watchHelper!.getSleep();
await watchHelper!.getSteps(); await watchHelper!.getSteps();
await watchHelper!.getActivity();
await watchHelper!.getBodyTemperature();
await watchHelper!.getBloodOxygen();
Result<dynamic> data = await watchHelper!.retrieveData();
if(data.isError) {
print('Unable to get the data');
}
var response = jsonDecode(data.asValue?.value?.toString()?.trim().replaceAll("\n", "")??"");
VitalsWRTType vitals = VitalsWRTType.fromMap(response);
log("the data is ${vitals}");
}catch(e){ }catch(e){
print('Error getting heart rate: $e'); print('Error getting heart rate: $e');
} }

@ -0,0 +1,56 @@
class Vitals {
final String value;
final String timestamp;
Vitals({
required this.value,
required this.timestamp,
});
factory Vitals.fromMap(Map<dynamic, dynamic> map) {
return Vitals(
value: map['value'] ?? "",
timestamp: map['timestamp'] ?? "",
);
}
}
class VitalsWRTType {
final List<Vitals> heartRate;
final List<Vitals> sleep;
final List<Vitals> step;
final List<Vitals> activity;
final List<Vitals> bodyOxygen;
final List<Vitals> bodyTemperature;
VitalsWRTType({required this.bodyOxygen, required this.bodyTemperature, required this.heartRate, required this.sleep, required this.step, required this.activity});
factory VitalsWRTType.fromMap(Map<dynamic, dynamic> map) {
List<Vitals> activity = [];
List<Vitals> steps = [];
List<Vitals> sleeps = [];
List<Vitals> heartRate = [];
List<Vitals> bodyOxygen = [];
List<Vitals> bodyTemperature = [];
map["activity"].forEach((element) {
activity.add(Vitals.fromMap(element));
});
map["steps"].forEach((element) {
steps.add(Vitals.fromMap(element));
});
map["sleep"].forEach((element) {
sleeps.add(Vitals.fromMap(element));
});
map["heartRate"].forEach((element) {
heartRate.add(Vitals.fromMap(element));
});
map["bloodOxygen"].forEach((element) {
bodyOxygen.add(Vitals.fromMap(element));
});
map["bodyTemperature"].forEach((element) {
bodyTemperature.add(Vitals.fromMap(element));
});
return VitalsWRTType(bodyTemperature: bodyTemperature, bodyOxygen: bodyOxygen, heartRate: heartRate, sleep: sleeps, step: steps, activity: activity);
}
}

@ -44,4 +44,37 @@ class SamsungPlatformChannel {
return Result.error(e); return Result.error(e);
} }
} }
Future<Result<bool>> getActivity() async {
try{
await _channel.invokeMethod('activitySummary');
return Result.value(true);
}catch(e){
return Result.error(e);
}
}
Future<Result<dynamic>> retrieveData() async {
try{
return Result.value(await _channel.invokeMethod('retrieveData'));
}catch(e){
return Result.error(e);
}
}
Future<Result<dynamic>> getBloodOxygen() async {
try{
return Result.value(await _channel.invokeMethod('bloodOxygen'));
}catch(e){
return Result.error(e);
}
}
Future<Result<dynamic>> getBodyTemperature() async {
try{
return Result.value(await _channel.invokeMethod('bodyTemperature'));
}catch(e){
return Result.error(e);
}
}
} }

@ -48,5 +48,42 @@ class SamsungHealth extends WatchHelper {
print('Error getting heart rate: $e'); print('Error getting heart rate: $e');
} }
} }
@override
Future<void> getActivity() async{
try {
await platformChannel.getActivity();
}catch(e){
print('Error getting heart rate: $e');
}
}
@override
Future<dynamic> retrieveData() async{
try {
return await platformChannel.retrieveData();
}catch(e){
print('Error getting heart rate: $e');
}
}
@override
Future<dynamic> getBloodOxygen() async{
try {
return await platformChannel.getBloodOxygen();
}catch(e){
print('Error getting heart rate: $e');
}
}
@override
Future<dynamic> getBodyTemperature() async {
try {
return await platformChannel.getBodyTemperature();
}catch(e){
print('Error getting heart rate: $e');
}
}
} }

@ -5,5 +5,9 @@ abstract class WatchHelper {
FutureOr<void> getHeartRate(); FutureOr<void> getHeartRate();
FutureOr<void> getSleep(); FutureOr<void> getSleep();
FutureOr<void> getSteps(); FutureOr<void> getSteps();
Future<void> getActivity();
Future<dynamic> retrieveData();
Future<dynamic> getBodyTemperature();
Future<dynamic> getBloodOxygen();
} }
Loading…
Cancel
Save