From 7233137e93613f847da8c4768b885439466f4cda Mon Sep 17 00:00:00 2001 From: youtaol Date: Thu, 5 Sep 2013 14:33:37 +0800 Subject: [PATCH] Use the activity type of current track to calculate calorie. --- MyTracks/res/values/strings.xml | 6 +++ .../mytracks/AggregatedStatsActivity.java | 4 +- .../apps/mytracks/content/TrackDataHub.java | 3 +- .../mytracks/fragments/ChartFragment.java | 3 +- .../fragments/MarkerDetailFragment.java | 3 +- .../mytracks/fragments/StatsFragment.java | 6 ++- .../io/file/AbstractFileTrackImporter.java | 11 ++---- .../mytracks/io/maps/SendMapsAsyncTask.java | 3 +- .../services/TrackRecordingService.java | 14 ++----- .../mytracks/stats/TripStatisticsUpdater.java | 33 +++++++++++++--- .../apps/mytracks/util/CalorieUtils.java | 38 ++++++++++++++++++- .../apps/mytracks/util/StatsUtils.java | 27 +++++++++---- .../apps/mytracks/stats/TripStatistics.java | 14 +++++-- .../stats/TripStatisticsUpdaterTest.java | 7 ++-- 14 files changed, 124 insertions(+), 48 deletions(-) diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 05e38ed43..ebca1149e 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -2146,6 +2146,12 @@ limitations under the License. Character limit: ~23 (1 line)"> Calories + + Calories(Invalid type) + Fastest pace diff --git a/MyTracks/src/com/google/android/apps/mytracks/AggregatedStatsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/AggregatedStatsActivity.java index e270e44b6..32c8c417d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/AggregatedStatsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/AggregatedStatsActivity.java @@ -19,6 +19,7 @@ package com.google.android.apps.mytracks; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.StatsUtils; import com.google.android.maps.mytracks.R; @@ -36,7 +37,8 @@ public class AggregatedStatsActivity extends AbstractMyTracksActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - StatsUtils.setTripStatisticsValues(this, getTripStatistics()); + StatsUtils.setTripStatisticsValues(this, getTripStatistics(), + PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); StatsUtils.setLocationValues(this, null, false); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java index c15a75543..fef7ba73c 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java @@ -579,8 +579,7 @@ public class TrackDataHub implements DataSourceListener { * * @return the selectedTrackId */ - @VisibleForTesting - long getSelectedTrackId() { + public long getSelectedTrackId() { return selectedTrackId; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java index 7ec6ab351..e030666ff 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java @@ -451,8 +451,7 @@ public class ChartFragment extends Fragment implements TrackDataListener { double power = Double.NaN; if (tripStatisticsUpdater != null) { - tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils - .getInt(getActivity(), R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); + tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, getActivity()); TripStatistics tripStatistics = tripStatisticsUpdater.getTripStatistics(); if (chartByDistance) { double distance = tripStatistics.getTotalDistance() * UnitConversions.M_TO_KM; diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java index 8cdaa71e5..c16e1ac6f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java @@ -192,7 +192,8 @@ public class MarkerDetailFragment extends Fragment { TextView name = (TextView) getView().findViewById(R.id.marker_detail_statistics_name); name.setText(getString(R.string.generic_name_line, waypoint.getName())); - StatsUtils.setTripStatisticsValues(getActivity(), waypoint.getTripStatistics()); + StatsUtils.setTripStatisticsValues(getActivity(), waypoint.getTripStatistics(), + waypoint.getTrackId()); StatsUtils.setLocationValues(getActivity(), waypoint.getLocation(), false); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java index 72576cfab..b2d1352ae 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java @@ -259,7 +259,11 @@ public class StatsFragment extends Fragment implements TrackDataListener { * Updates the UI. */ private void updateUi(FragmentActivity activity) { - StatsUtils.setTripStatisticsValues(activity, lastTripStatistics); + StatsUtils.setTripStatisticsValues( + activity, + lastTripStatistics, + trackDataHub == null ? PreferencesUtils.RECORDING_TRACK_ID_DEFAULT : trackDataHub + .getSelectedTrackId()); StatsUtils.setLocationValues(activity, lastLocation, isSelectedTrackRecording()); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/AbstractFileTrackImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/AbstractFileTrackImporter.java index b7b2a7e5f..eff1dfead 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/AbstractFileTrackImporter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/AbstractFileTrackImporter.java @@ -243,11 +243,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track return; } trackTripStatisticstrackUpdater.addLocation(trackPoint, recordingDistanceInterval, - PreferencesUtils.getInt(context, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT)); - markerTripStatisticsUpdater.addLocation(trackPoint, recordingDistanceInterval, - PreferencesUtils.getInt(context, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT)); + context); + markerTripStatisticsUpdater.addLocation(trackPoint, recordingDistanceInterval, context); } if (waypoint.getLocation().getTime() > trackPoint.getTime()) { trackPoint = null; @@ -537,9 +534,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track trackData.tripStatisticsUpdater = new TripStatisticsUpdater( location.getTime() != -1L ? location.getTime() : trackData.importTime); } - trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, - PreferencesUtils.getInt(context, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT)); + trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); trackData.bufferedLocations[trackData.numBufferedLocations] = location; trackData.numBufferedLocations++; diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java index 3a75b97a7..1444cf82d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/maps/SendMapsAsyncTask.java @@ -277,8 +277,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask { sentStartMarker = true; } - tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils - .getInt(context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); + tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); if (i % elevationSamplingFrequency == 0) { distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance()); elevations.add(tripStatisticsUpdater.getSmoothedElevation()); diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index 734577843..0c2b6dcf2 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -659,13 +659,9 @@ public class TrackRecordingService extends Service { if (cursor.moveToLast()) { do { Location location = myTracksProviderUtils.createTrackPoint(cursor); - trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, - PreferencesUtils.getInt(context, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT)); + trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); if (location.getTime() > markerStartTime) { - markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, - PreferencesUtils.getInt(context, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT)); + markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); } } while (cursor.moveToPrevious()); } @@ -1005,10 +1001,8 @@ public class TrackRecordingService extends Service { try { Uri uri = myTracksProviderUtils.insertTrackPoint(location, track.getId()); long trackPointId = Long.parseLong(uri.getLastPathSegment()); - trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils - .getInt(context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); - markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils - .getInt(context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); + trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); + markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, context); updateRecordingTrack(track, trackPointId, LocationUtils.isValidLocation(location)); } catch (SQLiteException e) { /* diff --git a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java index 195de0018..ee78d7727 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java +++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java @@ -23,8 +23,11 @@ import static com.google.android.apps.mytracks.services.TrackRecordingService.PA import com.google.android.apps.mytracks.util.CalorieUtils; import com.google.android.apps.mytracks.util.CalorieUtils.ActivityType; import com.google.android.apps.mytracks.util.LocationUtils; +import com.google.android.apps.mytracks.util.PreferencesUtils; +import com.google.android.maps.mytracks.R; import com.google.common.annotations.VisibleForTesting; +import android.content.Context; import android.location.Location; import android.util.Log; @@ -118,14 +121,35 @@ public class TripStatisticsUpdater { stats.merge(currentSegment); return stats; } + + /** + * Adds a location. + * + * @param location the location + * @param minRecordingDistance the min recording distance + * @param context the context to get the weight and track category + */ + public void addLocation(Location location, int minRecordingDistance, Context context) { + int weight = PreferencesUtils.getInt(context, R.string.stats_weight_key, + PreferencesUtils.STATS_WEIGHT_DEFAULT); + addLocation( + location, + minRecordingDistance, + CalorieUtils.getActivityType(context, + PreferencesUtils.getLong(context, R.string.recording_track_id_key)), weight); + } /** * Adds a location. TODO: This assume location has a valid time. * * @param location the location * @param minRecordingDistance the min recording distance + * @param activityType the activity type of current track + * @param weight the weight to calculate calorie */ - public void addLocation(Location location, int minRecordingDistance, int weight) { + @VisibleForTesting + void addLocation(Location location, int minRecordingDistance, ActivityType activityType, + int weight) { // Always update time updateTime(location.getTime()); @@ -189,13 +213,10 @@ public class TripStatisticsUpdater { updateSpeed( location.getTime(), location.getSpeed(), lastLocation.getTime(), lastLocation.getSpeed()); } - - // TODO 1: How to get the value of weight. - // TODO 2: How to get the value of ActivityType. - + // Update calorie double calorie = CalorieUtils.getCalorie(lastMovingLocation, location, - gradeBuffer.getAverage(), weight, ActivityType.FOOT); + gradeBuffer.getAverage(), weight, activityType); currentSegment.addCalorie(calorie); lastLocation = location; diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java index ae417a315..3f57620b6 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java @@ -15,8 +15,13 @@ */ package com.google.android.apps.mytracks.util; +import com.google.android.apps.mytracks.content.MyTracksProviderUtils; +import com.google.android.apps.mytracks.content.Track; +import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.maps.mytracks.R; import com.google.common.annotations.VisibleForTesting; +import android.content.Context; import android.location.Location; /** @@ -64,7 +69,7 @@ public class CalorieUtils { * UnitConversions.KM_TO_M / UnitConversions.HR_TO_MIN; public enum ActivityType { - CYCLING, FOOT + CYCLING, FOOT, INVALID } /** @@ -213,7 +218,36 @@ public class CalorieUtils { */ public static double getCalorie(Location start, Location stop, double grade, int weight, ActivityType activityType) { + if (activityType == ActivityType.INVALID) { + return TripStatistics.INVALID_CALORIE; + } return ActivityType.CYCLING == activityType ? calculateCalorieCycling(start, stop, grade, weight) : calculateCalorieFoot(start, stop, grade, weight); } -} + + /** + * Gets the activity type for calculating calorie by the category of track. + * + * @param context current context + * @param trackId the id of track + * @return activityType the activity type of track. + */ + public static ActivityType getActivityType(Context context, long trackId) { + ActivityType activityType = ActivityType.INVALID; + + Track track = MyTracksProviderUtils.Factory.get(context).getTrack(trackId); + if (track != null) { + String category = track.getCategory(); + + if (category.equals(context.getString(R.string.activity_type_walking)) + || category.equals(context.getString(R.string.activity_type_running))) { + activityType = ActivityType.FOOT; + } else if (category.equals(context.getString(R.string.activity_type_cycling)) + || category.equals(context.getString(R.string.activity_type_biking))) { + activityType = ActivityType.CYCLING; + } + } + + return activityType; + } +} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java index 359440f33..37495a41e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java @@ -17,6 +17,7 @@ package com.google.android.apps.mytracks.util; import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.apps.mytracks.util.CalorieUtils.ActivityType; import com.google.android.maps.mytracks.R; import android.app.Activity; @@ -108,8 +109,10 @@ public class StatsUtils { * * @param activity the activity * @param tripStatistics the trip statistics + * @param trackId the id of track */ - public static void setTripStatisticsValues(Activity activity, TripStatistics tripStatistics) { + public static void setTripStatisticsValues(Activity activity, TripStatistics tripStatistics, + long trackId) { boolean metricUnits = PreferencesUtils.isMetricUnits(activity); boolean reportSpeed = PreferencesUtils.isReportSpeed(activity); @@ -183,12 +186,15 @@ public class StatsUtils { if (showCalorie) { calorieHorizontalLine.setVisibility(View.VISIBLE); calorieContainer.setVisibility(View.VISIBLE); - double calories = tripStatistics == null ? Double.NaN : tripStatistics.getCalorie(); - setCalorie(activity, R.id.stats_calorie, R.string.stats_calorie, calories); + double calories = Double.NaN; + if (tripStatistics != null) { + calories = tripStatistics.getCalorie(); + } + setCalorie(activity, R.id.stats_calorie, calories, trackId); } else { calorieHorizontalLine.setVisibility(View.GONE); calorieContainer.setVisibility(View.GONE); - } + } } /** @@ -336,11 +342,18 @@ public class StatsUtils { * * @param activity the activity * @param itemId the item id - * @param labelId the calorie label id * @param calorie the value of calorie + * @param trackId the id of track */ - private static void setCalorie(Activity activity, int itemId, int labelId, double calorie) { + private static void setCalorie(Activity activity, int itemId, double calorie, long trackId) { + int labelId = R.string.stats_calorie; + // Current activity type is not supported. + if (trackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT + && CalorieUtils.getActivityType(activity, trackId) == ActivityType.INVALID) { + labelId = R.string.stats_calorie_invalid_type; + } setItem(activity, itemId, labelId, - String.format(Locale.getDefault(), CALORIES_FORMAT, calorie), activity.getString(R.string.unit_calorie)); + String.format(Locale.getDefault(), CALORIES_FORMAT, calorie), + activity.getString(R.string.unit_calorie)); } } \ No newline at end of file diff --git a/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java b/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java index 24bc2dd04..7e330c626 100644 --- a/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java +++ b/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java @@ -65,6 +65,13 @@ public class TripStatistics implements Parcelable { // The calorie of current track. private double calorie; + + /** + * This value means the calorie value is invalid due to activity type is not + * supported. + */ + public static final double INVALID_CALORIE = -1; + /** * Default constructor. */ @@ -532,7 +539,6 @@ public class TripStatistics implements Parcelable { data.gradeExtremities.set(minGrade, maxGrade); data.calorie = source.readDouble(); - return data; } @@ -578,7 +584,9 @@ public class TripStatistics implements Parcelable { * @param calorieAdded add the value to the total calorie */ public void addCalorie(double calorieAdded) { - this.calorie += calorieAdded; + if (calorieAdded != INVALID_CALORIE) { + this.calorie += calorieAdded; + } } /** @@ -591,7 +599,7 @@ public class TripStatistics implements Parcelable { } /** - * Gets calories value. + * Gets calorie value. */ public double getCalorie() { return calorie; diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdaterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdaterTest.java index cb724b075..0aef3dc5b 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdaterTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdaterTest.java @@ -2,6 +2,7 @@ package com.google.android.apps.mytracks.stats; +import com.google.android.apps.mytracks.util.CalorieUtils.ActivityType; import com.google.android.apps.mytracks.util.PreferencesUtils; import android.location.Location; @@ -224,7 +225,7 @@ public class TripStatisticsUpdaterTest extends TestCase { Location location = getLocation(i + locationOffset, (i + locationOffset) * .001, MOVING_SPEED, startTime + (timeOffset + i) * TEN_SECONDS); tripStatisticsUpdater.addLocation(location, - PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, + PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, ActivityType.FOOT, PreferencesUtils.STATS_WEIGHT_DEFAULT); tripStatistics = tripStatisticsUpdater.getTripStatistics(); @@ -271,7 +272,7 @@ public class TripStatisticsUpdaterTest extends TestCase { Location location = getLocation( locationOffset, locationOffset * .001, 0, startTime + (i + timeOffset) * TEN_SECONDS); tripStatisticsUpdater.addLocation(location, - PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, + PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, ActivityType.FOOT, PreferencesUtils.STATS_WEIGHT_DEFAULT); tripStatistics = tripStatisticsUpdater.getTripStatistics(); @@ -309,7 +310,7 @@ public class TripStatisticsUpdaterTest extends TestCase { Location location = getLocation(i + locationOffset, (i + locationOffset) * .001, 99999, startTime + (timeOffset + i) * TEN_SECONDS); tripStatisticsUpdater.addLocation(location, - PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, + PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT, ActivityType.FOOT, PreferencesUtils.STATS_WEIGHT_DEFAULT); tripStatistics = tripStatisticsUpdater.getTripStatistics();