public bool RequestMotionPermission() { PermissionAuthorization status = CheckMotionPermission(); if (status == PermissionAuthorization.NotDetermined) { // There is no RequestPermission for CMMotionActivityManager. So we'll just start and stop recording. _activityManager.QueryActivity(NSDate.Now, NSDate.Now, NSOperationQueue.MainQueue, (activities, error) => { }); } else if (status == PermissionAuthorization.Denied || status == PermissionAuthorization.Restricted) { Device.OpenUri(new NSUrl("app-settings:")); } return(true); }
public void QueryForRecentActivityData(Action completionHandler) { var now = NSDate.Now; var dateComponents = new NSDateComponents(); dateComponents.SetValueForComponent(-7, NSCalendarUnit.Day); var startDay = NSCalendar.CurrentCalendar.DateByAddingComponents(dateComponents, now, NSCalendarOptions.None); activityManager.QueryActivity(startDay, now, MotionQueue, (activities, error) => { if (activities != null) { CreateActivityDataWithActivities(activities, completionHandler); } else if (error != null) { HandleError(error); } }); }
protected override IEnumerable <Datum> Poll(CancellationToken cancellationToken) { List <Datum> data = new List <Datum>(); // if this is the first poll (no existing query start time), set the query start time to the current time. we // used to set this to the maximally previous time per ios documentation (7 days), but this (1) causes issues // when triggering surveys on the basis of these activities (there might be hundreds of activities within the // past 7 days), and it also runs counter to the user's expectations that data will only be collected from the // time at which they have enrolled in the study and not from times prior. if (_queryStartTime == null) { _queryStartTime = DateTimeOffset.UtcNow; } ManualResetEvent queryWait = new ManualResetEvent(false); SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { try { CMMotionActivityManager activityManager = new CMMotionActivityManager(); activityManager.QueryActivity(_queryStartTime.Value.UtcDateTime.ToNSDate(), NSDate.Now, NSOperationQueue.CurrentQueue, (activities, error) => { try { if (error == null) { // process each activity, keeping track of most recent NSDate mostRecentActivityStartTime = null; foreach (CMMotionActivity activity in activities) { DateTimeOffset timestamp = new DateTimeOffset(activity.StartDate.ToDateTime(), TimeSpan.Zero); #region get confidence double confidence = 0; if (activity.Confidence == CMMotionActivityConfidence.Low) { confidence = 0.1; } else if (activity.Confidence == CMMotionActivityConfidence.Medium) { confidence = 0.5; } else if (activity.Confidence == CMMotionActivityConfidence.High) { confidence = 1; } else { SensusException.Report("Unrecognized confidence: " + activity.Confidence); } #endregion #region get activities Action <Activities> AddActivityDatum = activityType => { ActivityDatum activityDatum = new ActivityDatum(timestamp, activityType, ActivityPhase.Starting, ActivityState.Active, confidence); data.Add(activityDatum); }; if (activity.Stationary) { AddActivityDatum(Activities.Still); } if (activity.Walking) { AddActivityDatum(Activities.Walking); } if (activity.Running) { AddActivityDatum(Activities.Running); } if (activity.Automotive) { AddActivityDatum(Activities.InVehicle); } if (activity.Cycling) { AddActivityDatum(Activities.OnBicycle); } if (activity.Unknown) { AddActivityDatum(Activities.Unknown); } #endregion if (mostRecentActivityStartTime == null) { mostRecentActivityStartTime = activity.StartDate; } else { mostRecentActivityStartTime = mostRecentActivityStartTime.LaterDate(activity.StartDate); } } // set the next query start time one second after the most recent activity's start time if (mostRecentActivityStartTime != null) { _queryStartTime = new DateTime(mostRecentActivityStartTime.ToDateTime().Ticks, DateTimeKind.Utc).AddSeconds(1); } } else { throw new Exception("Error while querying activities: " + error); } } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while querying activities: " + ex, LoggingLevel.Normal, GetType()); } finally { queryWait.Set(); } }); } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while querying activities: " + ex, LoggingLevel.Normal, GetType()); queryWait.Set(); } }); WaitHandle.WaitAny(new[] { queryWait, cancellationToken.WaitHandle }); return(data); }
protected override IEnumerable <Datum> Poll(CancellationToken cancellationToken) { List <Datum> data = new List <Datum>(); if (_queryStartTime == null) { _queryStartTime = DateTimeOffset.UtcNow.AddDays(-7); // only the last 7 days of activities are stored: https://developer.apple.com/documentation/coremotion/cmmotionactivitymanager/1615929-queryactivitystarting } ManualResetEvent queryWait = new ManualResetEvent(false); SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { try { CMMotionActivityManager activityManager = new CMMotionActivityManager(); activityManager.QueryActivity(_queryStartTime.Value.UtcDateTime.ToNSDate(), NSDate.Now, NSOperationQueue.CurrentQueue, (activities, error) => { try { if (error == null) { // process each activity, keeping track of most recent NSDate mostRecentActivityStartTime = null; foreach (CMMotionActivity activity in activities) { DateTimeOffset timestamp = new DateTimeOffset(activity.StartDate.ToDateTime(), TimeSpan.Zero); #region get confidence double confidence = 0; if (activity.Confidence == CMMotionActivityConfidence.Low) { confidence = 0; } else if (activity.Confidence == CMMotionActivityConfidence.Medium) { confidence = 0.5; } else if (activity.Confidence == CMMotionActivityConfidence.High) { confidence = 1; } else { SensusException.Report("Unrecognized confidence: " + activity.Confidence); } #endregion #region get activities Action <Activities> AddActivityDatum = activityType => { ActivityDatum activityDatum = new ActivityDatum(timestamp, activityType, ActivityPhase.During, ActivityState.Active, confidence); data.Add(activityDatum); }; if (activity.Stationary) { AddActivityDatum(Activities.Still); } if (activity.Walking) { AddActivityDatum(Activities.Walking); } if (activity.Running) { AddActivityDatum(Activities.Running); } if (activity.Automotive) { AddActivityDatum(Activities.InVehicle); } if (activity.Cycling) { AddActivityDatum(Activities.OnBicycle); } if (activity.Unknown) { AddActivityDatum(Activities.Unknown); } #endregion if (mostRecentActivityStartTime == null) { mostRecentActivityStartTime = activity.StartDate; } else { mostRecentActivityStartTime = mostRecentActivityStartTime.LaterDate(activity.StartDate); } } // set the next query start time one second after the most recent activity's start time if (mostRecentActivityStartTime != null) { _queryStartTime = new DateTime(mostRecentActivityStartTime.ToDateTime().Ticks, DateTimeKind.Utc).AddSeconds(1); } } else { SensusServiceHelper.Get().Logger.Log("Error while querying activities: " + error, LoggingLevel.Normal, GetType()); } } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while querying activities: " + ex, LoggingLevel.Normal, GetType()); } finally { queryWait.Set(); } }); } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Exception while querying activities: " + ex, LoggingLevel.Normal, GetType()); queryWait.Set(); } }); WaitHandle.WaitAny(new[] { queryWait, cancellationToken.WaitHandle }); return(data); }