Beispiel #1
0
 private void ResetUI()
 {
     ToggleWorkoutButton.SetTitle("Crawl Baby Crawl");
     EnergyLabel.SetText("Energy: 0.0");
     HeartRateLabel.SetText("Heart Rate:N/A");
 }
Beispiel #2
0
        public void BeginWorkout(DateTime beginDate)
        {
            // Obtain the `HKObjectType` for active energy burned and the `HKUnit` for kilocalories.
            var activeEnergyType = HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned);

            if (activeEnergyType == null)
            {
                return;
            }
            // Obtain the `HKObjectType` for HeartRate.
            var heartRateType = HKQuantityType.Create(HKQuantityTypeIdentifier.HeartRate);

            if (heartRateType == null)
            {
                return;
            }


            var energyUnit    = HKUnit.Kilocalorie;
            var heartRateUnit = HKUnit.FromString("count/min");

            // Update properties.
            WorkoutBeginDate = beginDate;

            // Set up a predicate to obtain only samples from the local device starting from `beginDate`.

            var datePredicate = HKQuery.GetPredicateForSamples((NSDate)beginDate, null, HKQueryOptions.None);

            var devices         = new NSSet <HKDevice>(new HKDevice[] { HKDevice.LocalDevice });
            var devicePredicate = HKQuery.GetPredicateForObjectsFromDevices(devices);
            var predicate       = NSCompoundPredicate.CreateAndPredicate(new NSPredicate[] { datePredicate, devicePredicate });

            //Create a results handler to recreate the samples generated by a query of active energy samples so that they can be associated with this app in the move graph.It should be noted that if your app has different heuristics for active energy burned you can generate your own quantities rather than rely on those from the watch.The sum of your sample's quantity values should equal the energy burned value provided for the workout
            Action <List <HKSample> > sampleHandler;

            sampleHandler = (List <HKSample> samples) =>
            {
                DispatchQueue.MainQueue.DispatchAsync(delegate
                {
                    var accumulatedSamples = new List <HKQuantitySample>();

                    var initialActivityEnergy = CurrentActiveEnergyQuantity.GetDoubleValue(energyUnit);
                    double accumulatedValue   = initialActivityEnergy;
                    foreach (HKQuantitySample sample in samples)
                    {
                        accumulatedValue = accumulatedValue + sample.Quantity.GetDoubleValue(energyUnit);
                        var ourSample    = HKQuantitySample.FromType(activeEnergyType, sample.Quantity, sample.StartDate, sample.EndDate);
                        accumulatedSamples.Add(ourSample);
                    }

                    // Update the UI.
                    CurrentActiveEnergyQuantity = HKQuantity.FromQuantity(energyUnit, accumulatedValue);
                    EnergyLabel.SetText($"Energy: {accumulatedValue.ToString("F")}");

                    // Update our samples.
                    ActiveEnergySamples.AddRange(accumulatedSamples);
                });
            };

            // Create a query to report new Active Energy Burned samples to our app.
            var activeEnergyQuery = new HKAnchoredObjectQuery(activeEnergyType, predicate, null, HKSampleQuery.NoLimit, (query, addedObjects, deletedObjects, newAnchor, error) =>
            {
                if (error == null)
                {
                    // NOTE: `deletedObjects` are not considered in the handler as there is no way to delete samples from the watch during a workout
                    ActiveEnergySamples = new List <HKSample>(addedObjects);
                    sampleHandler(ActiveEnergySamples);
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            });

            // Assign the same handler to process future samples generated while the query is still active.
            activeEnergyQuery.UpdateHandler = (query, addedObjects, deletedObjects, newAnchor, error) =>
            {
                if (error == null)
                {
                    ActiveEnergySamples = new List <HKSample>(addedObjects);
                    sampleHandler(ActiveEnergySamples);
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            };

            // Start Query
            CurrentQuery = activeEnergyQuery;
            HealthStore.ExecuteQuery(activeEnergyQuery);

            Action <List <HKSample> > heartRateSampler = (List <HKSample> samples) =>
            {
                foreach (HKQuantitySample sample in samples)
                {
                    _dangerousHeartRate.OnNext(sample.Quantity.GetDoubleValue(heartRateUnit));
                }
                DispatchQueue.MainQueue.DispatchAsync(delegate
                {
                    var sample = samples.LastOrDefault() as HKQuantitySample;
                    if (sample != null)
                    {
                        HeartRateLabel.SetText($"Heart Rate: {sample.Quantity.GetDoubleValue(heartRateUnit).ToString()}");
                    }
                });
            };

            HeartRateQuery = new HKAnchoredObjectQuery(heartRateType, predicate, null, HKSampleQuery.NoLimit, (query, addedObjects, deletedObjects, newAnchor, error) =>
            {
                if (error == null)
                {
                    // NOTE: `deletedObjects` are not considered in the handler as there is no way to delete samples from the watch during a workout
                    sampleHandler(new List <HKSample>(addedObjects));
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            });
            // Assign the same handler to process future samples generated while the query is still active.
            (HeartRateQuery as HKAnchoredObjectQuery).UpdateHandler = (query, addedObjects, deletedObjects, newAnchor, error) =>
            {
                if (error == null)
                {
                    heartRateSampler(new List <HKSample>(addedObjects));
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            };
            HealthStore.ExecuteQuery(HeartRateQuery);
        }