protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); Window.SetFlags(WindowManagerFlags.KeepScreenOn, WindowManagerFlags.KeepScreenOn); // Toolbar settings var mToolbar = FindViewById <Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar); SetSupportActionBar(mToolbar); SupportActionBar.Title = "Running Tracker"; // Find view _speedTextView = FindViewById <TextView>(Resource.Id.speed); _distanceTextView = FindViewById <TextView>(Resource.Id.distance); _mainButton = FindViewById <Button>(Resource.Id.mainButton); _txtTime = FindViewById <TextView>(Resource.Id.txtTimer); // Initialization _mainButtonState = MainButtonStates.Calibrating; _sumDistance = 0; _previousStateOfCurrentPolyline = null; _polylineOptions = null; _lastUserPosition = null; _userPosition = null; _lastRunningSpeedType = RunningSpeed.StartPoint; // Current position timer _currentPositionTimer = new UserPositionTimer(Fps, Model.GpsMinTime); _currentPositionTimer.Elapsed += CurrentPositionTimerOnElapsed; // Eventhandler _mainButton.Click += MainButton_Clicked; // Map fragment _mapFragment = FragmentManager.FindFragmentByTag("map") as MapFragment; if (_mapFragment == null) { var mapOptions = new GoogleMapOptions() .InvokeMapType(GoogleMap.MapTypeNormal) .InvokeZoomControlsEnabled(false) .InvokeZoomGesturesEnabled(true) .InvokeScrollGesturesEnabled(false) .InvokeCompassEnabled(true) .InvokeZOrderOnTop(false); var fragTx = FragmentManager.BeginTransaction(); _mapFragment = MapFragment.NewInstance(mapOptions); fragTx.Add(Resource.Id.map, _mapFragment, "map"); fragTx.Commit(); } _mapFragment.GetMapAsync(this); }
public LocationData(double longitude, double latitude, double speed = 0, double distance = 0, double up = 0, double down = 0, RunningSpeed runningSpeed = RunningSpeed.Normal) { Speed = speed; Longitude = longitude; Latitude = latitude; Distance = distance; Up = up; Down = down; RunningSpeedType = runningSpeed; }
/// <summary> /// Mainbutton is clicked /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">Event args</param> private void MainButton_Clicked(object sender, EventArgs e) { switch (_mainButtonState) { case MainButtonStates.Calibrating: Toast.MakeText(this, "GPS calibration in progress, please wait.", ToastLength.Long).Show(); break; case MainButtonStates.Start: try { _lastRunningSpeedType = RunningSpeed.StartPoint; Model.StartRunning(); _userPosition?.Remove(); _userPosition = null; _polylineOptions = null; _previousStateOfCurrentPolyline = null; _map.Clear(); DrawUser(_lastUserPosition); _distanceTextView.Text = "0"; _sumDistance = 0; _speedTextView.Text = "0"; _mainButtonState = MainButtonStates.Stop; _mainButton.Text = "Stop"; } catch (GpsNotReadyException) { Toast.MakeText(this, "GPS is not calibrated.", ToastLength.Long).Show(); } break; case MainButtonStates.Stop: var saved = Model.StopRunning(); _mainButtonState = MainButtonStates.Start; _mainButton.Text = "Start"; if (saved) { Toast.MakeText(this, "Running was saved", ToastLength.Long).Show(); } else { Toast.MakeText(this, "Running wasn't saved", ToastLength.Long).Show(); } break; } }
/// <summary> /// Start a new running /// </summary> public void StartRunning() { if (_remaningCalibratingLocation == 0) { _runningEnd = false; _runningData = new RunningData(CurrentPersonalDatas); _speedWarningFrequency = SpeedWarningFrequency; _distanceWarningYet = false; _timeWarningYet = false; _numOfContinuouslyStopsForSignal = NumOfContinuouslyStopsForSignal; _checkVerticalDistanceRemaining = 0; _previousRunningSpeed = RunningSpeed.StartPoint; _remaningSameColor = 0; _runningTimer.Start(); } else { throw new GpsNotReadyException(); } }
/// <summary> /// Add new point to the polyline /// </summary> /// <param name="sender">Sender object</param> /// <param name="e">User's new position</param> private void Model_NewPosition(object sender, PositionArgs e) { var position = new LatLng(e.LocationData.Latitude, e.LocationData.Longitude); // Refresh texts _speedTextView.Text = Math.Round(e.LocationData.Speed, 2).ToString(CultureInfo.InvariantCulture); _sumDistance = _sumDistance + e.LocationData.Distance; _distanceTextView.Text = Math.Round(_sumDistance, 2).ToString(CultureInfo.InvariantCulture); // Add new line if (e.LocationData.RunningSpeedType != _lastRunningSpeedType) { LatLng lastPosition = null; if (_previousStateOfCurrentPolyline != null) { lastPosition = _polylineOptions.Points.Last(); } _previousStateOfCurrentPolyline = null; _lastRunningSpeedType = e.LocationData.RunningSpeedType; _polylineOptions = new PolylineOptions(); switch (e.LocationData.RunningSpeedType) { case RunningSpeed.Slow: _polylineOptions.InvokeColor(Color.Rgb(238, 163, 54)); break; case RunningSpeed.Normal: _polylineOptions.InvokeColor(Color.Rgb(51, 127, 192)); break; case RunningSpeed.Fast: _polylineOptions.InvokeColor(Color.Rgb(33, 175, 95)); break; case RunningSpeed.StartPoint: break; default: throw new ArgumentOutOfRangeException(); } _polylineOptions.InvokeZIndex(5); if (lastPosition != null) { _polylineOptions.Add(lastPosition); } } _polylineOptions.Add(position); // Drawing the line var timer = new Timer(); timer.Interval = Model.GpsMinTime / 2; timer.Elapsed += (o, args) => { RunOnUiThread(() => { var currentPolyline = _map.AddPolyline(_polylineOptions); _previousStateOfCurrentPolyline?.Remove(); _previousStateOfCurrentPolyline = currentPolyline; }); timer.Stop(); }; timer.Start(); }
/// <summary> /// Change the user's location /// </summary> /// <param name="location">New location</param> public void ChangeLocation(Location location) { if (_remaningCalibratingLocation > 0) { // Calibrating the gps if (location.Accuracy <= DefaultGpsAccuracy) { _remaningCalibratingLocation--; } if (_remaningCalibratingLocation == 0) { OnGPS_Ready(new LocationData(location.Longitude, location.Latitude)); } } else { // The gps is calibrated if (_runningEnd) { return; } if (location.Accuracy > DefaultGpsAccuracy) { return; } if (_runningData == null) { // The running is not started if (location.Speed > 0) { OnUserPosition(new LocationData(location.Longitude, location.Latitude)); OnCameraPosition(new LocationData(location.Longitude, location.Latitude)); } return; } OnUserPosition(new LocationData(location.Longitude, location.Latitude)); // Reduce the warning frequencies if (_speedWarningFrequency > 0) { _speedWarningFrequency--; } if (location.Speed == 0) { if (_numOfContinuouslyStopsForSignal >= 0) { // If the var was 0 that will be -1, so the signal won't be sent again _numOfContinuouslyStopsForSignal--; } if (_numOfContinuouslyStopsForSignal == 0) { bool near = false; foreach (Position coordinate in _runningData.Stops) { near = location.DistanceTo(new Location("gps") { Longitude = coordinate.Longitude, Latitude = coordinate.Latitude }) < 3 * 14; } if (!near) { OnUserStopped(new LocationData(location.Longitude, location.Latitude, 0, 0, 0, 0, RunningSpeed.Slow)); _runningData.AddStop(new Position(location.Latitude, location.Longitude)); } } } else { _numOfContinuouslyStopsForSignal = NumOfContinuouslyStopsForSignal; } // If the user's position is not changed do nothing if (_previousLocation != null && location.Speed == 0) { return; } if (_checkVerticalDistanceRemaining == 0) { _oldLocation = location; } _checkVerticalDistanceRemaining++; _previousLocation = _currentLocation; _currentLocation = location; double distance = 0; double verticalDistance = 0; if (_previousLocation != null) { distance = _currentLocation.DistanceTo(_previousLocation); if (_checkVerticalDistanceRemaining % NumOfCheckVerticalDistance == 0) { verticalDistance = _currentLocation.Altitude - _oldLocation.Altitude; _checkVerticalDistanceRemaining = 0; } } double up = 0; double down = 0; if (verticalDistance > 0) { up = verticalDistance; } else { down = -verticalDistance; } double speed = location.Speed * 3.6; RunningSpeed runningSpeed; if (_remaningSameColor == 0) { if (speed < CurrentWarningValues.MinimumSpeed) { runningSpeed = RunningSpeed.Slow; } else if (speed > CurrentWarningValues.MaximumSpeed) { runningSpeed = RunningSpeed.Fast; } else { runningSpeed = RunningSpeed.Normal; } if (runningSpeed != _previousRunningSpeed && _previousRunningSpeed != RunningSpeed.StartPoint) { _remaningSameColor = MinLengthOfSameColor; } } else { _remaningSameColor--; runningSpeed = _previousRunningSpeed; } _previousRunningSpeed = runningSpeed; LocationData currentLocationData = new LocationData(location.Longitude, location.Latitude, speed, distance, up, down, runningSpeed); _runningData.AddLocation(currentLocationData); OnNewPosition(currentLocationData); // Send warning signals if (!_timeWarningYet && _runningData.Duration > CurrentWarningValues.Time) { _timeWarningYet = true; OnWarning(WarningType.Time); } if (!_distanceWarningYet && _runningData.Distance > CurrentWarningValues.Distance) { _distanceWarningYet = true; OnWarning(WarningType.Distance); } if (_speedWarningFrequency == 0) { if (_currentLocation.Speed * 3.6 < CurrentWarningValues.MinimumSpeed) { _speedWarningFrequency = SpeedWarningFrequency; OnWarning(WarningType.SpeedSlow); } if (_currentLocation.Speed * 3.6 > CurrentWarningValues.MaximumSpeed) { _speedWarningFrequency = SpeedWarningFrequency; OnWarning(WarningType.SpeedFast); } } } }