diff --git a/MyTracks/res/layout/stats_content.xml b/MyTracks/res/layout/stats_content.xml
index 9fa4abfff..b5748d095 100644
--- a/MyTracks/res/layout/stats_content.xml
+++ b/MyTracks/res/layout/stats_content.xml
@@ -142,5 +142,12 @@ limitations under the License.
+
+
\ No newline at end of file
diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index 1fe178933..bc383f7e3 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -2141,6 +2141,12 @@ limitations under the License.
Character limit: ~23 (1 line)">
Calories
+
+ Setup Activity 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/TrackEditActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackEditActivity.java
index 6295c7a5e..0a479b78e 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/TrackEditActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/TrackEditActivity.java
@@ -20,9 +20,12 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.fragments.ChooseActivityTypeDialogFragment;
import com.google.android.apps.mytracks.fragments.ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller;
+import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
+import com.google.android.apps.mytracks.util.CalorieUtils;
import com.google.android.apps.mytracks.util.TrackIconUtils;
import com.google.android.apps.mytracks.util.TrackNameUtils;
+import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.graphics.Bitmap;
@@ -57,6 +60,7 @@ public class TrackEditActivity extends AbstractMyTracksActivity
private static final String ICON_VALUE_KEY = "icon_value_key";
private Long trackId;
+ private TrackRecordingServiceConnection trackRecordingServiceConnection;
private MyTracksProviderUtils myTracksProviderUtils;
private Track track;
private String iconValue;
@@ -70,6 +74,7 @@ public class TrackEditActivity extends AbstractMyTracksActivity
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
+ trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
trackId = getIntent().getLongExtra(EXTRA_TRACK_ID, -1L);
if (trackId == -1L) {
Log.e(TAG, "invalid trackId");
@@ -180,6 +185,15 @@ public class TrackEditActivity extends AbstractMyTracksActivity
public void onClick(View v) {
track.setName(name.getText().toString());
String category = activityType.getText().toString();
+ if (!category.equals(track.getCategory())) {
+ // TODO Is there no race condition when setCalorie is called.
+ double calorie = CalorieUtils.calculateTrackCalorie(getApplicationContext(), track,
+ category);
+
+ track.getTripStatistics().setCalorie(calorie);
+ TrackRecordingServiceConnectionUtils.updateCalorie(trackRecordingServiceConnection,
+ calorie);
+ }
track.setCategory(category);
track.setIcon(TrackIconUtils.getIconValue(TrackEditActivity.this, category));
track.setDescription(description.getText().toString());
@@ -209,6 +223,18 @@ public class TrackEditActivity extends AbstractMyTracksActivity
cancel.setVisibility(View.VISIBLE);
}
}
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ TrackRecordingServiceConnectionUtils.startConnection(this, trackRecordingServiceConnection);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ trackRecordingServiceConnection.unbind();
+ }
@Override
public void onSaveInstanceState(Bundle outState) {
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 c3013db26..85bd7b2af 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java
@@ -587,8 +587,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 6d55b0d36..e030666ff 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java
@@ -34,7 +34,6 @@ import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
-import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@@ -189,7 +188,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
public void onSampledInTrackPoint(Location location) {
if (isResumed()) {
double[] data = new double[ChartView.NUM_SERIES + 1];
- fillDataPoint(getActivity(), location, data);
+ fillDataPoint(location, data);
pendingPoints.add(data);
}
}
@@ -197,14 +196,14 @@ public class ChartFragment extends Fragment implements TrackDataListener {
@Override
public void onSampledOutTrackPoint(Location location) {
if (isResumed()) {
- fillDataPoint(getActivity(), location, null);
+ fillDataPoint(location, null);
}
}
@Override
public void onSegmentSplit(Location location) {
if (isResumed()) {
- fillDataPoint(getActivity(), location, null);
+ fillDataPoint(location, null);
}
}
@@ -438,12 +437,11 @@ public class ChartFragment extends Fragment implements TrackDataListener {
* data[5] = cadence
* data[6] = power
*
- * @param context the context
* @param location the location
* @param data the data point to fill in, can be null
*/
@VisibleForTesting
- void fillDataPoint(Context context, Location location, double data[]) {
+ void fillDataPoint(Location location, double data[]) {
double timeOrDistance = Double.NaN;
double elevation = Double.NaN;
double speed = Double.NaN;
@@ -453,9 +451,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
double power = Double.NaN;
if (tripStatisticsUpdater != null) {
- int weight = PreferencesUtils.getInt(
- context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT);
- tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, weight);
+ 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..c544891fa 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java
@@ -24,6 +24,7 @@ import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PhotoUtils;
+import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
@@ -192,7 +193,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(),
+ PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
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/importer/AbstractFileTrackImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java
index df9706ff2..7d62b172a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/importer/AbstractFileTrackImporter.java
@@ -242,11 +242,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;
@@ -549,9 +546,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..8e33cb9c6 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) {
/*
@@ -1339,5 +1333,34 @@ public class TrackRecordingService extends Service {
deathRecipient.binderDied();
}
}
+
+ @Override
+ public void updateCalorie(double calorie) {
+ if (!canAccess()) {
+ return;
+ }
+ trackRecordingService.updateCalorie(calorie);
+ }
+ }
+
+ /**
+ * Updates the calorie value.
+ *
+ * @param calorie new calorie value.
+ */
+ public void updateCalorie(final double calorie) {
+ if (myTracksLocationManager == null || executorService == null
+ || !myTracksLocationManager.isAllowed() || executorService.isShutdown()
+ || executorService.isTerminated()) {
+ return;
+ }
+ executorService.submit(new Runnable() {
+ @Override
+ public void run() {
+ trackTripStatisticsUpdater.updateCalorie(calorie);
+ }
+ });
+
+
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java
index 6eff79b67..1b815ed51 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java
@@ -74,6 +74,7 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
@SuppressWarnings("deprecation")
ListPreference listPreference = (ListPreference) findPreference(getString(R.string.stats_units_key));
OnPreferenceChangeListener listener = new OnPreferenceChangeListener() {
+
@Override
public boolean onPreferenceChange(Preference pref, Object newValue) {
configRateListPreference(PreferencesUtils.STATS_UNITS_DEFAULT.equals((String) newValue));
@@ -83,6 +84,10 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
* activity.
*/
updateWeightSummary(PreferencesUtils.STATS_UNITS_DEFAULT.equals((String) newValue));
+ // Recreate weight value dialog.
+ removeDialog(WEIGHT_INPUT_DIALOG);
+ onCreateDialog(WEIGHT_INPUT_DIALOG);
+
return true;
}
};
@@ -134,7 +139,8 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
case WEIGHT_INPUT_DIALOG:
final EditText weightInput = new EditText(this);
weightInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
- weightInput.setText(Integer.toString(PreferencesUtils.STATS_WEIGHT_DEFAULT));
+ weightInput.setText(Integer.toString(getWeightDisplayValue(PreferencesUtils
+ .isMetricUnits(getApplicationContext()))));
weightInput.setSelectAllOnFocus(true);
dialog = (new AlertDialog.Builder(this))
.setMessage(R.string.settings_stats_calorie_weight_description)
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 0d50f7542..c153dad19 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java
@@ -22,8 +22,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;
@@ -119,14 +122,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());
@@ -190,18 +214,24 @@ 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;
lastMovingLocation = location;
}
+
+ /**
+ * Updates the calorie value.
+ *
+ * @param calorie new calorie value.
+ */
+ public void updateCalorie(double calorie) {
+ currentSegment.setCalorie(calorie);
+ }
/**
* Gets the smoothed elevation over several readings. The elevation readings
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..e17d0fad9 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.MyTracksProviderUtils.LocationIterator;
+import com.google.android.apps.mytracks.content.Track;
+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
}
/**
@@ -128,14 +133,14 @@ public class CalorieUtils {
* @param grade the grade to calculate
* @param weight of rider plus bike, in kilogram
* @param timeUsed how many times used in second
- * @return the power value watts(Joule/second).
+ * @return the calorie value in kcal.
*/
@VisibleForTesting
static double calculateCyclingCalorie(double speed, double grade, int weight, double timeUsed) {
// Get the Power, the unit is Watt (Joule/second)
double power = earthGravity * weight * speed * (K1 + grade) + K2 * (speed * speed * speed);
- // Get the calories
+ // Get the calories in kcal
return power * timeUsed / UnitConversions.KCAL_TO_J;
}
@@ -213,7 +218,89 @@ public class CalorieUtils {
*/
public static double getCalorie(Location start, Location stop, double grade, int weight,
ActivityType activityType) {
+ if (activityType == ActivityType.INVALID) {
+ return 0.0;
+ }
return ActivityType.CYCLING == activityType ? calculateCalorieCycling(start, stop, grade,
weight) : calculateCalorieFoot(start, stop, grade, weight);
}
-}
+
+ /**
+ * Gets the activity type for calculating calorie by the id 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;
+ }
+
+ /**
+ * Gets the activity type for calculating calorie by the category of track.
+ *
+ * @param context current context
+ * @param category the category of track
+ * @return activityType the activity type of track.
+ */
+ public static ActivityType getActivityType(Context context, String category) {
+ ActivityType activityType = ActivityType.INVALID;
+ 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;
+ }
+
+ /**
+ * Calculates the calorie of track.
+ *
+ * @param context the context
+ * @param track the track to calculate
+ * @param category the category of track
+ */
+ public static double calculateTrackCalorie(Context context, Track track, String category) {
+ ActivityType activityType = getActivityType(context, category);
+ if (activityType == ActivityType.INVALID) {
+ return 0.0;
+ }
+
+ double calorie = 0.0;
+ MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(context);
+ long trackId = track.getId();
+ LocationIterator points = providerUtils.getTrackPointLocationIterator(trackId, -1, false,
+ MyTracksProviderUtils.DEFAULT_LOCATION_FACTORY);
+ // TODO How get grade
+ double grade = 0;
+ if (points.hasNext()) {
+ Location start = points.next();
+ while (points.hasNext()) {
+ Location stop = points.next();
+ calorie += getCalorie(start, stop, grade, PreferencesUtils.getInt(context,
+ R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT), activityType);
+ start = stop;
+ }
+ }
+ return calorie;
+ }
+
+}
\ 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..a481af233 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java
@@ -16,12 +16,18 @@
package com.google.android.apps.mytracks.util;
+import com.google.android.apps.mytracks.TrackEditActivity;
+import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
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;
+import android.content.Intent;
import android.location.Location;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
import android.widget.TextView;
import java.util.Locale;
@@ -108,8 +114,9 @@ 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);
@@ -181,14 +188,20 @@ public class StatsUtils {
View calorieContainer = activity.findViewById(R.id.stats_calorie_container);
if (showCalorie) {
+ if(trackId == PreferencesUtils.RECORDING_TRACK_ID_DEFAULT) {
+ return;
+ }
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 +349,45 @@ 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 which is used to start track edit activity
+ * when user want to change the activity type
*/
- private static void setCalorie(Activity activity, int itemId, int labelId, double calorie) {
- setItem(activity, itemId, labelId,
- String.format(Locale.getDefault(), CALORIES_FORMAT, calorie), activity.getString(R.string.unit_calorie));
+ private static void setCalorie(final Activity activity, int itemId, double calorie,
+ final long trackId) {
+ String calorieString;
+ View view = activity.findViewById(itemId);
+ Button button = (Button) activity.findViewById(R.id.stats_calorie_setup);
+ MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(activity);
+ ActivityType activityType = CalorieUtils.getActivityType(activity,
+ providerUtils.getTrack(trackId).getCategory());
+ // Current activity type is not supported.
+ if (activityType == ActivityType.INVALID) {
+ button.setVisibility(View.VISIBLE);
+ view.setVisibility(View.GONE);
+
+ /*
+ * Return when it is not a valid track, which may be aggregated stats or
+ * marker.
+ */
+ if (trackId == PreferencesUtils.RECORDING_TRACK_ID_DEFAULT) {
+ button.setVisibility(View.GONE);
+ return;
+ }
+ button.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = IntentUtils.newIntent(activity, TrackEditActivity.class).putExtra(
+ TrackEditActivity.EXTRA_TRACK_ID, trackId);
+ activity.startActivity(intent);
+ }
+ });
+ } else {
+ button.setVisibility(View.GONE);
+ view.setVisibility(View.VISIBLE);
+ calorieString = String.format(Locale.getDefault(), CALORIES_FORMAT, calorie);
+ setItem(activity, itemId, R.string.stats_calorie, calorieString,
+ activity.getString(R.string.unit_calorie));
+ }
}
}
\ No newline at end of file
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/TrackRecordingServiceConnectionUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/TrackRecordingServiceConnectionUtils.java
index f84351386..afe817669 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/TrackRecordingServiceConnectionUtils.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/TrackRecordingServiceConnectionUtils.java
@@ -193,4 +193,24 @@ public class TrackRecordingServiceConnectionUtils {
Toast.makeText(context, R.string.marker_add_error, Toast.LENGTH_LONG).show();
return -1L;
}
+
+ /**
+ * Updates the calorie of current recording track.
+ */
+ public static void updateCalorie(TrackRecordingServiceConnection trackRecordingServiceConnection,
+ double calorie) {
+ ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
+ .getServiceIfBound();
+ if (trackRecordingService == null) {
+ Log.d(TAG, "Unable to update calorie, no track recording service");
+ } else {
+ try {
+ trackRecordingService.updateCalorie(calorie);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to update calorie", e);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Unable to update calorie.", e);
+ }
+ }
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/UnitConversions.java b/MyTracks/src/com/google/android/apps/mytracks/util/UnitConversions.java
index cf20d82d2..7f5e0e2ec 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/UnitConversions.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/UnitConversions.java
@@ -78,5 +78,8 @@ public class UnitConversions {
public static final double DEG_TO_RAD = Math.PI / 180.0;
// multiplication factor to convert Kcal to joules.
- public static final double KCAL_TO_J = 4.184;
+ public static final double KCAL_TO_J = 4184;
+
+ // multiplication factor to convert joules to Kcal.
+ public static final double J_TO_KCAL = 1 / KCAL_TO_J;
}
diff --git a/MyTracksLib/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl b/MyTracksLib/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl
index 59b80b566..ba0d72833 100644
--- a/MyTracksLib/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl
+++ b/MyTracksLib/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl
@@ -106,4 +106,11 @@ interface ITrackRecordingService {
* return a Sensor.SensorState enum value.
*/
int getSensorState();
+
+ /**
+ * Updates the calorie value.
+ *
+ * @param calorie new calorie value.
+ */
+ void updateCalorie(double calorie);
}
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..52c2dece6 100644
--- a/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java
+++ b/MyTracksLib/src/com/google/android/apps/mytracks/stats/TripStatistics.java
@@ -63,7 +63,7 @@ public class TripStatistics implements Parcelable {
private final ExtremityMonitor gradeExtremities = new ExtremityMonitor();
// The calorie of current track.
- private double calorie;
+ private double calorie = 0.0;
/**
* Default constructor.
@@ -532,7 +532,6 @@ public class TripStatistics implements Parcelable {
data.gradeExtremities.set(minGrade, maxGrade);
data.calorie = source.readDouble();
-
return data;
}
@@ -578,7 +577,7 @@ public class TripStatistics implements Parcelable {
* @param calorieAdded add the value to the total calorie
*/
public void addCalorie(double calorieAdded) {
- this.calorie += calorieAdded;
+ calorie += calorieAdded;
}
/**
@@ -591,7 +590,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/fragments/ChartFragmentTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
index e4a8a88a4..f3f161669 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
@@ -359,7 +359,7 @@ public class ChartFragmentTest extends AndroidTestCase {
*/
private double[] fillDataPointTestHelper(Location location) {
double[] point = new double[ChartView.NUM_SERIES + 1];
- chartFragment.fillDataPoint(getContext(), location, point);
+ chartFragment.fillDataPoint(location, point);
return point;
}
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();
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/util/CalorieUtilsTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/util/CalorieUtilsTest.java
index b97d371d7..aac24349f 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/util/CalorieUtilsTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/util/CalorieUtilsTest.java
@@ -29,8 +29,8 @@ public class CalorieUtilsTest extends TestCase {
Location start = new Location(LocationManager.GPS_PROVIDER);
Location stop = new Location(LocationManager.GPS_PROVIDER);
- private double grade = 10.0;
- private int weight = 20;
+ private double grade = 0.07;
+ private int weight = 80;
private final long TIME_INTERVAL = 1000l;
@Override
@@ -94,4 +94,16 @@ public class CalorieUtilsTest extends TestCase {
assertEquals(expected, actual);
}
-}
+ /**
+ * Checks calculating cycling calorie.
+ */
+ public void testCalculateCalorieCycling() {
+ grade = 0;
+ weight = 90;
+ start.setSpeed(9);
+ stop.setSpeed(9);
+ double expected = 175 / 1000 / UnitConversions.KCAL_TO_J;
+ double actual = CalorieUtils.calculateCalorieCycling(start, stop, grade, weight);
+ assertEquals(expected, actual);
+ }
+}
\ No newline at end of file