public static Task <double> ReadCurrentHeightInMetres(HKHealthStore store)
        {
            var tcs = new TaskCompletionSource <double>();

            var heightType = HKQuantityTypeIdentifierKey.Height;
            var heightUnit = HKUnit.Meter;
            var sort       = new NSSortDescriptor(HKSample.SortIdentifierStartDate, false);

            var sampleType = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.Height);

            var query = new HKSampleQuery(sampleType, null, 1, new NSSortDescriptor[] { sort },
                                          (q, data, error) =>
            {
                if (error == null)
                {
                    var amount = (data[0] as HKQuantitySample).Quantity.GetDoubleValue(heightUnit);
                    tcs.TrySetResult(amount);
                }
                else
                {
                    tcs.TrySetException(new NSErrorException(error));
                }
            });

            store.ExecuteQuery(query);

            return(tcs.Task);
        }
		void UpdateJournal (object sender, EventArgs args)
		{
			var calendar = NSCalendar.CurrentCalendar;

			var startDate = DateTime.Now.Date;
			var endDate = startDate.AddDays(1);

			var sampleType = HKSampleType.GetQuantityType (HKQuantityTypeIdentifierKey.DietaryEnergyConsumed);
			var predicate = HKQuery.GetPredicateForSamples ((NSDate)startDate, (NSDate)endDate, HKQueryOptions.None);

			var query = new HKSampleQuery (sampleType, predicate, 0, new NSSortDescriptor[0], (resultQuery, results, error) => {
				if (error != null) {
					Console.WriteLine ("An error occured fetching the user's tracked food. " +
					"In your app, try to handle this gracefully. The error was: {0}.", error.LocalizedDescription);
					return;
				}

				InvokeOnMainThread (() => {
					FoodItems.RemoveAllObjects ();
					foreach (HKQuantitySample sample in results) {

						var foodName = (NSString)sample.Metadata.Dictionary [HKMetadataKey.FoodType];
						double joules = sample.Quantity.GetDoubleValue (HKUnit.Joule);
						var foodItem = FoodItem.Create (foodName, joules);

						FoodItems.Add (foodItem);
					}

					TableView.ReloadData ();
				});
			});

			HealthStore.ExecuteQuery (query);
		}
        void UpdateJournal(object sender, EventArgs args)
        {
            var calendar = NSCalendar.CurrentCalendar;

            var startDate = DateTime.Now.Date;
            var endDate   = startDate.AddDays(1);

            var sampleType = HKSampleType.GetQuantityType(HKQuantityTypeIdentifierKey.DietaryEnergyConsumed);
            var predicate  = HKQuery.GetPredicateForSamples((NSDate)startDate, (NSDate)endDate, HKQueryOptions.None);

            var query = new HKSampleQuery(sampleType, predicate, 0, new NSSortDescriptor[0], (resultQuery, results, error) => {
                if (error != null)
                {
                    Console.WriteLine("An error occured fetching the user's tracked food. " +
                                      "In your app, try to handle this gracefully. The error was: {0}.", error.LocalizedDescription);
                    return;
                }

                InvokeOnMainThread(() => {
                    FoodItems.RemoveAllObjects();
                    foreach (HKQuantitySample sample in results)
                    {
                        var foodName  = (NSString)sample.Metadata.Dictionary [HKMetadataKey.FoodType];
                        double joules = sample.Quantity.GetDoubleValue(HKUnit.Joule);
                        var foodItem  = FoodItem.Create(foodName, joules);

                        FoodItems.Add(foodItem);
                    }

                    TableView.ReloadData();
                });
            });

            HealthStore.ExecuteQuery(query);
        }
        public async Task <int> QueryLastRegistratetHeartRate()
        {
            var heartRateType            = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.HeartRate);
            int lastRegistratedHeartRate = 0;

            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(heartRateType, new NSPredicate(IntPtr.Zero), 1, new NSSortDescriptor[] { timeSortDescriptor },
                                          (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
                string resultString = string.Empty;
                string source       = string.Empty;
                HKQuantity quantity = null;
                if (results.Length != 0)
                {
                    resultString             = results [results.Length - 1].ToString();
                    lastRegistratedHeartRate = ParseHeartRateResultToBeatsPrMinute(resultString);
                    var quantiyResult        = (HKQuantitySample)results [results.Length - 1];
                    source = quantiyResult.Source.Name;

                    HealthKitDataContext.ActiveHealthKitData.HeartRateReadings.LastRegisteredHeartRate = lastRegistratedHeartRate;
                    HealthKitDataContext.ActiveHealthKitData.HeartRateReadings.Source = source;
                    Console.WriteLine(string.Format("lastRegistratedHeartRate: {0}", lastRegistratedHeartRate));
                }
            });
            await Task.Factory.StartNew(() => HealthKitStore.ExecuteQuery(query));

            return(lastRegistratedHeartRate);
        }
        void FetchMostRecentData(HKQuantityType quantityType, Action <HKQuantity, NSError> completion)
        {
            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(quantityType, null, 1, new NSSortDescriptor[] { timeSortDescriptor },
                                          (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
                if (completion != null && error != null)
                {
                    completion(null, error);
                    return;
                }

                HKQuantity quantity = null;
                if (results.Length != 0)
                {
                    var quantitySample = (HKQuantitySample)results [results.Length - 1];
                    quantity           = quantitySample.Quantity;
                }

                if (completion != null)
                {
                    completion(quantity, error);
                }
            });

            HealthStore.ExecuteQuery(query);
        }
Beispiel #6
0
        private void MakeWorkoutsSlothy(HKWorkout workout)
        {
            // Query for workout's rotes
            var routeType        = HKSeriesType.WorkoutRouteType;
            var workoutPredicate = HKQuery.GetPredicateForObjectsFromWorkout(workout);
            var routeQuery       = new HKSampleQuery(routeType, workoutPredicate, HKSampleQuery.NoLimit, null, (sender, results, error) =>
            {
                var route = results?.FirstOrDefault() as HKWorkoutRoute;
                if (route != null)
                {
                    var version = route.Metadata?.SyncVersion;
                    if (!version.HasValue)
                    {
                        Console.WriteLine($"Route does not have a sync version ({route})");
                    }
                    else if (version.Value == 1)
                    {
                        this.MakeRouteWorkoutsSlothy(workout, route);
                    }
                }
                else
                {
                    Console.WriteLine($"An error occurred fetching the route ({error?.LocalizedDescription ?? "Workout has no routes"})");
                }
            });

            this.healthStore.ExecuteQuery(routeQuery);
        }
Beispiel #7
0
        private void LoadWorkouts(Action <List <HKWorkout> > completion)
        {
            var workoutType = HKObjectType.GetWorkoutType();
            var predicate   = HKQuery.GetPredicateForObjectsFromSource(HKSource.GetDefaultSource);
            var query       = new HKSampleQuery(workoutType, predicate, HKSampleQuery.NoLimit, null, (sender, results, error) =>
            {
                var isSuccess = results != null;
                if (isSuccess)
                {
                    var workouts = results.OfType <HKWorkout>().ToList();
                    isSuccess    = workouts.Any();
                    if (isSuccess)
                    {
                        completion(workouts);
                    }
                }

                if (!isSuccess)
                {
                    Console.WriteLine($"An error occurred: ({error?.LocalizedDescription ?? "Unknown"})");
                }
            });

            this.healthStore.ExecuteQuery(query);
        }
        private void FetchMostRecentData(HKQuantityType quantityType, Action <List <HKSample>, NSError> completion, int days)
        {
            var      timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            DateTime startDay           = DateTime.Now;
            DateTime endDay             = startDay.AddDays(-days).AddHours(-startDay.Hour).AddMinutes(-startDay.Minute).AddSeconds(-startDay.Second).AddMilliseconds(-startDay.Millisecond);
            var      predicate          = HKQuery.GetPredicateForSamples(DateUtil.DateTimeToNSDate(endDay), DateUtil.DateTimeToNSDate(startDay), HKQueryOptions.None);
            var      query = new HKSampleQuery(quantityType, predicate, 0, new NSSortDescriptor[] { timeSortDescriptor },
                                               (HKSampleQuery resultQuery, HKSample[] results, NSError error) =>
            {
                if (completion != null && error != null)
                {
                    completion(null, error);
                    return;
                }

                completion?.Invoke(results.ToList(), error);
            });

            HealthStore.ExecuteQuery(query);
        }
        public int StepQuery()
        {
            var dateComponents = new NSDateComponents();

            dateComponents.Day = -1;
            var cal       = new NSCalendar(NSCalendarType.ISO8601);
            var yesterday = cal.DateFromComponents(dateComponents);
            var predicate = HKQuery.GetPredicateForSamples(yesterday, new NSDate(), HKQueryOptions.None);
            var query     = new HKSampleQuery(HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount),
                                              predicate,
                                              0,
                                              null,
                                              new HKSampleQueryResultsHandler((retQuery, results, error) => {
                Console.WriteLine(results.Length);
            }));

            _healthStore.ExecuteQuery(query);

            return(0);
        }
        public async Task <double> QueryTotalHeight()
        {
            var    heightType  = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.Height);
            double usersHeight = 0.0;

            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(heightType, new NSPredicate(IntPtr.Zero), 1, new NSSortDescriptor[] { timeSortDescriptor },
                                          (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
                HKQuantity quantity = null;
                if (results.Length != 0)
                {
                    var quantitySample = (HKQuantitySample)results [results.Length - 1];
                    quantity           = quantitySample.Quantity;
                    usersHeight        = quantity.GetDoubleValue(HKUnit.Meter);
                    HealthKitDataContext.ActiveHealthKitData.Height = usersHeight;

                    Console.WriteLine(string.Format("height of Fetched: {0}", usersHeight));
                }
            });
            await Task.Factory.StartNew(() => HealthKitStore.ExecuteQuery(query));

            return(usersHeight);
        }
        public async Task <int> QueryLastRegistratedSteps()
        {
            var stepType             = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount);
            int lastRegistratedSteps = 0;

            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(stepType, new NSPredicate(IntPtr.Zero), 1, new NSSortDescriptor[] { timeSortDescriptor },
                                          (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
                HKQuantity quantity = null;

                if (results.Length != 0)
                {
                    var quantitySample   = (HKQuantitySample)results [results.Length - 1];
                    quantity             = quantitySample.Quantity;
                    var source           = quantitySample.Source.Name;
                    lastRegistratedSteps = (int)quantity.GetDoubleValue(HKUnit.Count);
                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.TotalStepsOfLastRecording = lastRegistratedSteps;
                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.Source = source;
                }
            });

            m_healthKitStore.ExecuteQuery(query);
            return(lastRegistratedSteps);
        }
        public async Task <double> QueryLastRegistratedWalkingDistance()
        {
            var    distanceType = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.DistanceWalkingRunning);
            double lastRegistratedWalkingDistance = 0.0;

            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(distanceType, new NSPredicate(IntPtr.Zero), 1, new NSSortDescriptor[] { timeSortDescriptor },
                                          (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
                HKQuantity quantity = null;
                string resultString = string.Empty;
                if (results.Length != 0)
                {
                    var quantitySample             = (HKQuantitySample)results [results.Length - 1];
                    quantity                       = quantitySample.Quantity;
                    lastRegistratedWalkingDistance = quantity.GetDoubleValue(HKUnit.Meter);

                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.TotalDistanceOfLastRecording = lastRegistratedWalkingDistance;
                    Console.WriteLine(string.Format("value of QueryLastRegistratedWalkingDistance: {0}", lastRegistratedWalkingDistance));
                }
            });

            m_healthKitStore.ExecuteQuery(query);
            return(lastRegistratedWalkingDistance);
        }
        void RefreshQuantityValue(NSString quantityTypeKey, HKQuantityType quantityType)
        {
            NSSortDescriptor timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);

            // Since we are interested in retrieving the user's latest sample, we sort the samples in descending order, and set the limit to 1. We are not filtering the data, and so the predicate is set to nil.
            HKSampleQuery query = new HKSampleQuery(quantityType, null, 100, new NSSortDescriptor[] { timeSortDescriptor },
                                                    new HKSampleQueryResultsHandler(new Action <HKSampleQuery, HKSample[], NSError>((query2, results, error) =>
            {
                if (results != null && results.Length > 0)
                {
                    if (quantityTypeKey == HKQuantityTypeIdentifierKey.Height)
                    {
                        //We have height, process the last entry into inches.
                        var quantitySample = results.LastOrDefault() as HKQuantitySample;

                        var quantity = quantitySample.Quantity;

                        var heightUnit = HKUnit.Inch;

                        DispatchQueue.MainQueue.DispatchAsync(() => {
                            var dataStore = StateDispatcher <HealthState> .State;

                            HealthStateMutator.MutateHeight(dataStore,
                                                            () => quantity.GetDoubleValue(heightUnit));

                            StateDispatcher <HealthState> .Refresh();
                        });
                    }
                    else if (quantityTypeKey == HKQuantityTypeIdentifierKey.StepCount)
                    {
                        DispatchQueue.MainQueue.DispatchAsync(() => {
                            //Now we need to deliver all the blood glucose entries in a list to any listeners.
                            var entries = new List <StepCountEntry>();

                            //Now also deliver all blood glucose readings up to the UI via the 'diff engine' for easy UITableViewController based updating.
                            foreach (var entry in results)
                            {
                                var sample = entry as HKQuantitySample;
                                if (sample != null)
                                {
                                    entries.Add(new HealthKitStepCountEntry(sample));
                                }
                            }

                            HealthStateDispatchers.StepCountListStateDispatcher.Refresh(
                                entries.Cast <StepCountEntry>().ToList());
                        });
                    }
                    else if (quantityTypeKey == HKQuantityTypeIdentifierKey.BloodGlucose)
                    {
                        DispatchQueue.MainQueue.DispatchAsync(() => {
                            //Refresh the views with the last known blood glucose quantity via HealthState and BloodGlucoseRecommendationState.
                            var lastBloodGlucoseQuantity = (results.LastOrDefault() as HKQuantitySample).Quantity;

                            var healthState = StateDispatcher <HealthState> .State;

                            var mgPerDL = HKUnit.FromString("mg/dL");
                            HealthStateMutator.MutateBloodGlucose(healthState,
                                                                  () => lastBloodGlucoseQuantity.GetDoubleValue(mgPerDL));


                            //At this point all UI subscribers to the HealthState object will update.
                            StateDispatcher <HealthState> .Refresh();



                            var recommendationStore = StateDispatcher <BloodGlucoseRecommendationState> .State;

                            BloodGlucoseRecommendationMutator.MutateBloodGlucose(
                                recommendationStore, () => healthState.BloodGlucose);

                            //At this point all UI subscribers to the BloodGlucoseRecommendationState will update.
                            StateDispatcher <BloodGlucoseRecommendationState> .Refresh();



                            //Now we need to deliver all the blood glucose entries in a list to any listeners.
                            var newBloodGlucoseEntries = new List <HealthKitBloodGlucoseEntry>();

                            //Now also deliver all blood glucose readings up to the UI via the 'diff engine' for easy UITableViewController based updating.
                            foreach (var bloodGlucoseEntry in results)
                            {
                                var bloodGlucoseSample = bloodGlucoseEntry as HKQuantitySample;
                                if (bloodGlucoseSample != null)
                                {
                                    newBloodGlucoseEntries.Add(new HealthKitBloodGlucoseEntry(bloodGlucoseSample));
                                }
                            }

                            HealthStateDispatchers.BloodGlucoseListStateDispatcher.Refresh(
                                newBloodGlucoseEntries.Cast <BloodGlucoseEntry>().ToList());
                        });
                    }
                }
            })));

            HealthStore.ExecuteQuery(query);
        }
		void FetchMostRecentData (HKQuantityType quantityType, Action <HKQuantity, NSError> completion)
		{
			var timeSortDescriptor = new NSSortDescriptor (HKSample.SortIdentifierEndDate, false);
			var query = new HKSampleQuery (quantityType, null, 1, new NSSortDescriptor[] { timeSortDescriptor },
				            (HKSampleQuery resultQuery, HKSample[] results, NSError error) => {
					if (completion != null && error != null) {
						completion (null, error);
						return;
					}

					HKQuantity quantity = null;
					if (results.Length != 0) {
						var quantitySample = (HKQuantitySample)results [results.Length - 1];
						quantity = quantitySample.Quantity;
					}

					if (completion != null)
						completion (quantity, error);
				});

			HealthStore.ExecuteQuery (query);
		}
Beispiel #15
0
        protected override Task <IEnumerable <T> > Query <T>(HealthDataType healthDataType,
                                                             AggregateTime aggregateTime,
                                                             DateTime startDate, DateTime endDate)
        {
            if (_healthStore == null || !HKHealthStore.IsHealthDataAvailable)
            {
                throw new NotSupportedException("HealthKit data is not available on this device");
            }

            var authorized = IsAuthorizedToRead(healthDataType);

            if (!authorized)
            {
                throw new UnauthorizedAccessException($"Not enough permissions to request {healthDataType}");
            }

            var taskComplSrc  = new TaskCompletionSource <IEnumerable <T> >();
            var healthKitType = healthDataType.ToHealthKit();
            var quantityType  = HKQuantityType.Create(healthKitType.QuantityTypeIdentifier);
            var predicate     = HKQuery.GetPredicateForSamples((NSDate)startDate, (NSDate)endDate, HKQueryOptions.StrictStartDate);

            if (aggregateTime != AggregateTime.None)
            {
                var anchor   = NSCalendar.CurrentCalendar.DateBySettingsHour(0, 0, 0, NSDate.Now, NSCalendarOptions.None);
                var interval = new NSDateComponents();

                switch (aggregateTime)
                {
                case AggregateTime.Year:
                    interval.Year = 1;
                    break;

                case AggregateTime.Month:
                    interval.Month = 1;
                    break;

                case AggregateTime.Week:
                    interval.Week = 1;
                    break;

                case AggregateTime.Day:
                    interval.Day = 1;
                    break;

                case AggregateTime.Hour:
                    interval.Hour = 1;
                    break;
                }

                HKStatisticsOptions hkStatisticsOptions;

                if (healthKitType.Cumulative)
                {
                    hkStatisticsOptions = HKStatisticsOptions.CumulativeSum;
                }
                else
                {
                    hkStatisticsOptions = HKStatisticsOptions.DiscreteAverage |
                                          HKStatisticsOptions.DiscreteMax |
                                          HKStatisticsOptions.DiscreteMax;
                }

                var queryAggregate = new HKStatisticsCollectionQuery(quantityType, predicate, hkStatisticsOptions,
                                                                     anchor, interval)
                {
                    InitialResultsHandler = (collectionQuery, results, error) =>
                    {
                        var healthData = new List <T>();

                        foreach (var result in results.Statistics)
                        {
                            var hData = new AggregatedHealthData
                            {
                                StartDate = (DateTime)result.StartDate,
                                EndDate   = (DateTime)result.EndDate,
                            };

                            if (healthKitType.Cumulative)
                            {
                                hData.Sum = result.SumQuantity().GetDoubleValue(healthKitType.Unit);
                            }
                            else
                            {
                                hData.Min     = result.MinimumQuantity().GetDoubleValue(healthKitType.Unit);
                                hData.Max     = result.MaximumQuantity().GetDoubleValue(healthKitType.Unit);
                                hData.Average = result.AverageQuantity().GetDoubleValue(healthKitType.Unit);
                            }

                            healthData.Add(hData as T);
                        }

                        taskComplSrc.SetResult(healthData);
                    }
                };

                _healthStore.ExecuteQuery(queryAggregate);
            }
            else
            {
                var sortDescriptor = new[] { new NSSortDescriptor(HKSample.SortIdentifierEndDate, true) };


                HKSampleType sampleType;

                if (healthKitType.HKType == HealthKitData.HKTypes.Category)
                {
                    sampleType = HKCategoryType.Create(healthKitType.CategoryTypeIdentifier);
                }
                else if (healthKitType.HKType == HealthKitData.HKTypes.Quantity)
                {
                    sampleType = HKQuantityType.Create(healthKitType.QuantityTypeIdentifier);
                }
                else if (healthKitType.HKType == HealthKitData.HKTypes.Workout)
                {
                    sampleType = HKSampleType.GetWorkoutType();
                }
                else
                {
                    throw new NotSupportedException();
                }

                var query = new HKSampleQuery(sampleType, predicate,
                                              HKSampleQuery.NoLimit, sortDescriptor,
                                              (resultQuery, results, error) =>
                {
                    IEnumerable <T> healthData = default(IEnumerable <T>);

                    if (sampleType == HKSampleType.GetWorkoutType())
                    {
                        healthData = results?.Select(result => new WorkoutData
                        {
                            StartDate   = (DateTime)result.StartDate,
                            EndDate     = (DateTime)result.EndDate,
                            Duration    = (result as HKWorkout).Duration,
                            Device      = (result as HKWorkout).Device?.ToString(),
                            WorkoutType = (result as HKWorkout).WorkoutDataType()
                                          //TotalDistance = Convert.ToDouble((result as HKWorkout).TotalDistance),
                                          //TotalEnergyBurned = Convert.ToDouble((result as HKWorkout).TotalEnergyBurned)
                        } as T);
                    }
                    else
                    {
                        healthData = results?.Select(result => new HealthData
                        {
                            StartDate   = (DateTime)result.StartDate,
                            EndDate     = (DateTime)result.EndDate,
                            Value       = ReadValue(result, healthKitType.Unit),
                            UserEntered = result.Metadata?.WasUserEntered ?? false,
                        } as T);
                    }



                    taskComplSrc.SetResult(healthData);
                });

                _healthStore.ExecuteQuery(query);
            }

            return(taskComplSrc.Task);
        }
        void FetchData2(HKCategoryType quantityType, Action<HKSample[], NSError> completion)
        {
            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(quantityType, null, 100, null,
                            (HKSampleQuery resultQuery, HKSample[] results, NSError error) =>
                            {
                                if (completion != null && error != null)
                                {
                                    completion(null, error);
                                    return;
                                }

                                if (completion != null)
                                    completion(results, error);
                            });

            HealthStore.ExecuteQuery(query);
        }