forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -41,6 +41,8 @@ limitations under the License.
|
||||
<string name="stats_rate_key">statsRate</string>
|
||||
<string name="stats_show_coordinate_key">statsShowCoordinate</string>
|
||||
<string name="stats_show_grade_elevation_key">statsShowGradeElevation</string>
|
||||
<string name="stats_show_calorie_key">statsShowCalorie</string>
|
||||
<string name="stats_weight_key">statsWeight</string>
|
||||
<string name="stats_units_key">statsUnits</string>
|
||||
<string name="track_color_mode_medium_key">trackColorModeMedium</string>
|
||||
<string name="track_color_mode_percentage_key">trackColorModePercentage</string>
|
||||
|
||||
@@ -2014,6 +2014,16 @@ limitations under the License.
|
||||
Character limit: ~23 (1 line)">
|
||||
Grade/Elevation
|
||||
</string>
|
||||
<string name="settings_stats_calorie_weight"
|
||||
translation_description="In the 'Stats settings, the option to configure user's weight.
|
||||
|
||||
Character limit: ~23 (1 line)">
|
||||
Weight
|
||||
</string>
|
||||
<string name="settings_stats_calorie_weight_description"
|
||||
translation_description="In the 'Stats settings, the description message about weight setting item.">
|
||||
Weight for calculating calories.
|
||||
</string>
|
||||
<string name="settings_stats_rate_title"
|
||||
translation_description="In the 'Stats' settings, the option to change the preferred rate,
|
||||
either speed (mi/hr) or pace (min/mi).
|
||||
@@ -2134,7 +2144,7 @@ limitations under the License.
|
||||
translation_description="In the 'Stats' page, the calorie burned.
|
||||
|
||||
Character limit: ~23 (1 line)">
|
||||
Calorie expenditure
|
||||
Calories
|
||||
</string>
|
||||
<string name="stats_fastest_pace"
|
||||
translation_description="In the 'Stats' page, the fastest pace.">
|
||||
@@ -2491,6 +2501,12 @@ limitations under the License.
|
||||
%1$d: an integer value. E.g., '2'.">
|
||||
%1$d km
|
||||
</string>
|
||||
<string name="value_integer_kilogram"
|
||||
translation_description="Display an integer value in kilogram (kg).
|
||||
|
||||
%1$d: an integer value. E.g., '2'.">
|
||||
%1$d kg
|
||||
</string>
|
||||
<string name="value_integer_kilometer_hour"
|
||||
translation_description="Display an integer value in kilometers per hour (km/h).
|
||||
|
||||
@@ -2552,6 +2568,12 @@ limitations under the License.
|
||||
%1$d: an integer value. E.g., '2'.">
|
||||
%1$d %%
|
||||
</string>
|
||||
<string name="value_integer_pound"
|
||||
translation_description="Display an integer value in pound (lb).
|
||||
|
||||
%1$d: an integer value. E.g., '2'.">
|
||||
%1$d lb
|
||||
</string>
|
||||
<string name="value_integer_second"
|
||||
translation_description="In a setting picker, the string format to display an integer value in
|
||||
seconds (s).
|
||||
|
||||
@@ -33,5 +33,16 @@ limitations under the License.
|
||||
android:defaultValue="false"
|
||||
android:key="@string/stats_show_coordinate_key"
|
||||
android:title="@string/settings_stats_coordinate" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/stats_show_calorie_key"
|
||||
android:title="@string/stats_calorie" />
|
||||
<EditTextPreference
|
||||
android:dependency="@string/stats_show_calorie_key"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="number"
|
||||
android:key="@string/stats_weight_key"
|
||||
android:persistent="false"
|
||||
android:title="@string/settings_stats_calorie_weight" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
@@ -451,7 +451,8 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
double power = Double.NaN;
|
||||
|
||||
if (tripStatisticsUpdater != null) {
|
||||
tripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils
|
||||
.getInt(getActivity(), R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT));
|
||||
TripStatistics tripStatistics = tripStatisticsUpdater.getTripStatistics();
|
||||
if (chartByDistance) {
|
||||
double distance = tripStatistics.getTotalDistance() * UnitConversions.M_TO_KM;
|
||||
|
||||
+9
-3
@@ -242,8 +242,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
// No more track points. Ignore the rest of the waypoints.
|
||||
return;
|
||||
}
|
||||
trackTripStatisticstrackUpdater.addLocation(trackPoint, recordingDistanceInterval);
|
||||
markerTripStatisticsUpdater.addLocation(trackPoint, recordingDistanceInterval);
|
||||
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));
|
||||
}
|
||||
if (waypoint.getLocation().getTime() > trackPoint.getTime()) {
|
||||
trackPoint = null;
|
||||
@@ -533,7 +537,9 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
|
||||
trackData.tripStatisticsUpdater = new TripStatisticsUpdater(
|
||||
location.getTime() != -1L ? location.getTime() : trackData.importTime);
|
||||
}
|
||||
trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval,
|
||||
PreferencesUtils.getInt(context, R.string.stats_weight_key,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT));
|
||||
|
||||
trackData.bufferedLocations[trackData.numBufferedLocations] = location;
|
||||
trackData.numBufferedLocations++;
|
||||
|
||||
@@ -277,7 +277,8 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
|
||||
sentStartMarker = true;
|
||||
}
|
||||
|
||||
tripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
tripStatisticsUpdater.addLocation(location, recordingDistanceInterval, PreferencesUtils
|
||||
.getInt(context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT));
|
||||
if (i % elevationSamplingFrequency == 0) {
|
||||
distances.add(tripStatisticsUpdater.getTripStatistics().getTotalDistance());
|
||||
elevations.add(tripStatisticsUpdater.getSmoothedElevation());
|
||||
|
||||
@@ -659,9 +659,13 @@ public class TrackRecordingService extends Service {
|
||||
if (cursor.moveToLast()) {
|
||||
do {
|
||||
Location location = myTracksProviderUtils.createTrackPoint(cursor);
|
||||
trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval,
|
||||
PreferencesUtils.getInt(context, R.string.stats_weight_key,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT));
|
||||
if (location.getTime() > markerStartTime) {
|
||||
markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval,
|
||||
PreferencesUtils.getInt(context, R.string.stats_weight_key,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT));
|
||||
}
|
||||
} while (cursor.moveToPrevious());
|
||||
}
|
||||
@@ -1001,8 +1005,10 @@ public class TrackRecordingService extends Service {
|
||||
try {
|
||||
Uri uri = myTracksProviderUtils.insertTrackPoint(location, track.getId());
|
||||
long trackPointId = Long.parseLong(uri.getLastPathSegment());
|
||||
trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval);
|
||||
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));
|
||||
updateRecordingTrack(track, trackPointId, LocationUtils.isValidLocation(location));
|
||||
} catch (SQLiteException e) {
|
||||
/*
|
||||
|
||||
@@ -17,12 +17,22 @@
|
||||
package com.google.android.apps.mytracks.settings;
|
||||
|
||||
import com.google.android.apps.mytracks.util.PreferencesUtils;
|
||||
import com.google.android.apps.mytracks.util.UnitConversions;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* An activity for accessing stats settings.
|
||||
@@ -31,12 +41,25 @@ import android.preference.Preference.OnPreferenceChangeListener;
|
||||
*/
|
||||
public class StatsSettingsActivity extends AbstractSettingsActivity {
|
||||
|
||||
private static final String TAG = MapSettingsActivity.class.getSimpleName();
|
||||
|
||||
private CheckBoxPreference caloriePreference;
|
||||
private EditTextPreference weightPreference;
|
||||
|
||||
private static final int WEIGHT_INPUT_DIALOG = 1;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
addPreferencesFromResource(R.xml.stats_settings);
|
||||
|
||||
caloriePreference = (CheckBoxPreference) findPreference(getString(R.string.stats_show_calorie_key));
|
||||
weightPreference = (EditTextPreference) findPreference(getString(R.string.stats_weight_key));
|
||||
|
||||
configCaloriePreference();
|
||||
configWeightPreference();
|
||||
updateWeightSummary();
|
||||
/*
|
||||
* Note configureUnitsListPreference will trigger
|
||||
* configureRateListPreference
|
||||
@@ -49,17 +72,22 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
|
||||
*/
|
||||
private void configUnitsListPreference() {
|
||||
@SuppressWarnings("deprecation")
|
||||
ListPreference listPreference = (ListPreference) findPreference(
|
||||
getString(R.string.stats_units_key));
|
||||
ListPreference listPreference = (ListPreference) findPreference(getString(R.string.stats_units_key));
|
||||
OnPreferenceChangeListener listener = new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference pref, Object newValue) {
|
||||
configRateListPreference(PreferencesUtils.STATS_UNITS_DEFAULT.equals((String) newValue));
|
||||
|
||||
/*
|
||||
* It is necessary to change the weight summary as they are in the same
|
||||
* activity.
|
||||
*/
|
||||
updateWeightSummary(PreferencesUtils.STATS_UNITS_DEFAULT.equals((String) newValue));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
String value = PreferencesUtils.getString(
|
||||
this, R.string.stats_units_key, PreferencesUtils.STATS_UNITS_DEFAULT);
|
||||
String value = PreferencesUtils.getString(this, R.string.stats_units_key,
|
||||
PreferencesUtils.STATS_UNITS_DEFAULT);
|
||||
String[] values = getResources().getStringArray(R.array.stats_units_values);
|
||||
String[] options = getResources().getStringArray(R.array.stats_units_options);
|
||||
configureListPreference(listPreference, options, options, values, value, listener);
|
||||
@@ -72,13 +100,157 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
|
||||
*/
|
||||
private void configRateListPreference(boolean metricUnits) {
|
||||
@SuppressWarnings("deprecation")
|
||||
ListPreference listPreference = (ListPreference) findPreference(
|
||||
getString(R.string.stats_rate_key));
|
||||
String value = PreferencesUtils.getString(
|
||||
this, R.string.stats_rate_key, PreferencesUtils.STATS_RATE_DEFAULT);
|
||||
ListPreference listPreference = (ListPreference) findPreference(getString(R.string.stats_rate_key));
|
||||
String value = PreferencesUtils.getString(this, R.string.stats_rate_key,
|
||||
PreferencesUtils.STATS_RATE_DEFAULT);
|
||||
String[] values = getResources().getStringArray(R.array.stats_rate_values);
|
||||
String[] options = getResources().getStringArray(
|
||||
metricUnits ? R.array.stats_rate_metric_options : R.array.stats_rate_imperial_options);
|
||||
configureListPreference(listPreference, options, options, values, value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the calorie preference.
|
||||
*
|
||||
* @param reference to configure
|
||||
* @param key of the preference
|
||||
* @param defaultValue default value of this preference
|
||||
*/
|
||||
private void configCaloriePreference() {
|
||||
caloriePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
boolean value = (Boolean) newValue;
|
||||
if (value) {
|
||||
showDialog(WEIGHT_INPUT_DIALOG);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
Dialog dialog = null;
|
||||
switch (id) {
|
||||
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.setSelectAllOnFocus(true);
|
||||
dialog = (new AlertDialog.Builder(this))
|
||||
.setMessage(R.string.settings_stats_calorie_weight_description)
|
||||
.setNegativeButton(R.string.generic_cancel, null)
|
||||
.setPositiveButton(R.string.generic_ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialogInterface, int number) {
|
||||
storeWeightValue(weightInput.getText().toString());
|
||||
updateWeightSummary();
|
||||
dialogInterface.cancel();
|
||||
}
|
||||
}).setTitle(R.string.settings_stats_calorie_weight).setView(weightInput).create();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the weight preference.
|
||||
*
|
||||
* @param preference to configure
|
||||
* @param key of the preference
|
||||
* @param defaultValue default value of this preference
|
||||
* @param isEnable true means enable the weight preference
|
||||
*/
|
||||
private void configWeightPreference() {
|
||||
weightPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
storeWeightValue((String) newValue);
|
||||
updateWeightSummary();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
weightPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference pref) {
|
||||
int value = getWeightDisplayValue(PreferencesUtils.isMetricUnits(getApplicationContext()));
|
||||
((EditTextPreference) pref).getEditText().setText(String.valueOf(value));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the weight summary.
|
||||
*
|
||||
* @param preference the preference
|
||||
* @param keyId the key id
|
||||
* @param defaultValue the default value
|
||||
*/
|
||||
private void updateWeightSummary() {
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(this);
|
||||
updateWeightSummary(metricUnits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the weight summary.
|
||||
*
|
||||
* @param preference the preference
|
||||
* @param keyId the key id
|
||||
* @param defaultValue the default value
|
||||
* @param metricUnits the status of metric units
|
||||
*/
|
||||
private void updateWeightSummary(boolean metricUnits) {
|
||||
int displayValue = getWeightDisplayValue(metricUnits);
|
||||
weightPreference.setSummary(getString(metricUnits ? R.string.value_integer_kilogram
|
||||
: R.string.value_integer_pound, displayValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the weight display value in metric or imperial depending on the
|
||||
* preferred units.
|
||||
*
|
||||
* @param keyId the key id
|
||||
* @param defaultValue the default value
|
||||
*/
|
||||
private int getWeightDisplayValue(boolean metricUnits) {
|
||||
int value = PreferencesUtils.getInt(this, R.string.stats_weight_key,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT);
|
||||
if (!metricUnits) {
|
||||
value = (int) Math.round(value * UnitConversions.KG_TO_LB);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the weight value, always in metric units.
|
||||
*
|
||||
* @param keyId the key id
|
||||
* @param defaultValue the default value
|
||||
* @param displayValue the display value
|
||||
*/
|
||||
private void storeWeightValue(String displayValue) {
|
||||
/*
|
||||
* TODO add a method to an abstract class or an utility class to avoid
|
||||
* duplicating store preference logic in MapSettingsActivity.java.
|
||||
*/
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(displayValue);
|
||||
if (!PreferencesUtils.isMetricUnits(this)) {
|
||||
value = (int) (value * UnitConversions.LB_TO_KG);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "invalid value " + displayValue);
|
||||
value = PreferencesUtils.STATS_WEIGHT_DEFAULT;
|
||||
}
|
||||
|
||||
PreferencesUtils.setInt(this, R.string.stats_weight_key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +93,6 @@ public class TripStatisticsUpdater {
|
||||
|
||||
// A buffer of the recent speed readings (m/s) for calculating max speed
|
||||
private final DoubleBuffer speedBuffer = new DoubleBuffer(SPEED_SMOOTHING_FACTOR);
|
||||
|
||||
// Default weight, in kilogram
|
||||
private int defaultWeight = 65;
|
||||
|
||||
/**
|
||||
* Creates a new trip statistics updater.
|
||||
@@ -128,7 +125,7 @@ public class TripStatisticsUpdater {
|
||||
* @param location the location
|
||||
* @param minRecordingDistance the min recording distance
|
||||
*/
|
||||
public void addLocation(Location location, int minRecordingDistance) {
|
||||
public void addLocation(Location location, int minRecordingDistance, int weight) {
|
||||
// Always update time
|
||||
updateTime(location.getTime());
|
||||
|
||||
@@ -195,10 +192,10 @@ public class TripStatisticsUpdater {
|
||||
|
||||
// TODO 1: How to get the value of weight.
|
||||
// TODO 2: How to get the value of ActivityType.
|
||||
|
||||
|
||||
// Update calorie
|
||||
double calorie = CalorieUtils.getCalories(lastMovingLocation, location,
|
||||
gradeBuffer.getAverage(), defaultWeight, ActivityType.FOOT);
|
||||
double calorie = CalorieUtils.getCalorie(lastMovingLocation, location,
|
||||
gradeBuffer.getAverage(), weight, ActivityType.FOOT);
|
||||
currentSegment.addCalorie(calorie);
|
||||
|
||||
lastLocation = location;
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
* Utils to calculate caloric expenditure.
|
||||
* Utils to calculate calories.
|
||||
*
|
||||
* @author youtaol
|
||||
*/
|
||||
@@ -76,7 +76,7 @@ public class CalorieUtils {
|
||||
* @return the VO2 value in ml/kg/min.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double calculateWalkingVo2(double speed, double grade) {
|
||||
static double getLowSpeedFootVo2(double speed, double grade) {
|
||||
// Change meters per second to meters per minute
|
||||
speed = speed / UnitConversions.S_TO_MIN;
|
||||
/*
|
||||
@@ -97,7 +97,7 @@ public class CalorieUtils {
|
||||
* @return the VO2 value in ml/kg/min.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double calculateRunningVo2(double speed, double grade) {
|
||||
static double getHighSpeedFootVo2(double speed, double grade) {
|
||||
// Change meters per second to meters per minute
|
||||
speed = speed / UnitConversions.S_TO_MIN;
|
||||
/*
|
||||
@@ -131,7 +131,7 @@ public class CalorieUtils {
|
||||
* @return the power value watts(Joule/second).
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double calculateCyclingCalories(double speed, double grade, int weight, double timeUsed) {
|
||||
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);
|
||||
|
||||
@@ -140,16 +140,16 @@ public class CalorieUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the calories expenditure by cycling.
|
||||
* Calculates the calories by cycling.
|
||||
*
|
||||
* @param start the start location
|
||||
* @param stop the stop location
|
||||
* @param grade the grade to calculate
|
||||
* @param weight the weight of user, in kilogram
|
||||
* @return the calories expenditure between the start and stop location.
|
||||
* @return the calories between the start and stop location.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double calculateExpenditureCycling(Location start, Location stop, double grade, int weight) {
|
||||
static double calculateCalorieCycling(Location start, Location stop, double grade, int weight) {
|
||||
// Gets duration in seconds
|
||||
double duration = (double) (stop.getTime() - start.getTime()) * UnitConversions.MS_TO_S;
|
||||
// Get speed in meters per second
|
||||
@@ -158,25 +158,24 @@ public class CalorieUtils {
|
||||
grade = 0.0;
|
||||
}
|
||||
|
||||
return calculateCyclingCalories(speed, grade, weight, duration);
|
||||
return calculateCyclingCalorie(speed, grade, weight, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the calories expenditure by running or walking.
|
||||
* Calculates the calories by running or walking.
|
||||
*
|
||||
* @param start the start location
|
||||
* @param stop the stop location
|
||||
* @param grade the grade to calculate
|
||||
* @param weight the weight of user, in kilogram
|
||||
* @return the calories expenditure between the start and stop location, in
|
||||
* calories.
|
||||
* @return the calories between the start and stop location, in calories.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double calculateExpenditureFoot(Location start, Location stop, double grade, int weight) {
|
||||
static double calculateCalorieFoot(Location start, Location stop, double grade, int weight) {
|
||||
// Get speed in meters per second
|
||||
double averageSpeed = (start.getSpeed() + stop.getSpeed()) / 2.0;
|
||||
// Get VO2 in mL/kg/min
|
||||
double vo2 = getVo2(averageSpeed, grade);
|
||||
double vo2 = getFootVo2(averageSpeed, grade);
|
||||
// Minutes
|
||||
double time = (double) (stop.getTime() - start.getTime()) * UnitConversions.MS_TO_S
|
||||
* UnitConversions.S_TO_MIN;
|
||||
@@ -193,31 +192,28 @@ public class CalorieUtils {
|
||||
* @return the VO2 value.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static double getVo2(double speed, double grade) {
|
||||
static double getFootVo2(double speed, double grade) {
|
||||
if (grade < 0) {
|
||||
grade = 0.0;
|
||||
}
|
||||
|
||||
return speed > CRTICAL_SPEED_RUNNING ? calculateRunningVo2(speed, grade) : calculateWalkingVo2(
|
||||
return speed > CRTICAL_SPEED_RUNNING ? getHighSpeedFootVo2(speed, grade) : getLowSpeedFootVo2(
|
||||
speed, grade);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the calories expenditure between two locations.
|
||||
* Calculates the calories between two locations.
|
||||
*
|
||||
* @param start the start location
|
||||
* @param stop the stop location
|
||||
* @param grade the grade to calculate
|
||||
* @param weight the weight of user
|
||||
* @param activityType can be foot or cycling
|
||||
* @return the calories expenditure between the start and stop location.
|
||||
* @return the calories between the start and stop location.
|
||||
*/
|
||||
public static double getCalories(Location start, Location stop, double grade, int weight,
|
||||
public static double getCalorie(Location start, Location stop, double grade, int weight,
|
||||
ActivityType activityType) {
|
||||
if (ActivityType.CYCLING == activityType) {
|
||||
return calculateExpenditureCycling(start, stop, grade, weight);
|
||||
} else {
|
||||
return calculateExpenditureFoot(start, stop, grade, weight);
|
||||
}
|
||||
return ActivityType.CYCLING == activityType ? calculateCalorieCycling(start, stop, grade,
|
||||
weight) : calculateCalorieFoot(start, stop, grade, weight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ public class PreferencesUtils {
|
||||
public static final boolean STATS_SHOW_COORDINATE_DEFAULT = false;
|
||||
public static final boolean STATS_SHOW_GRADE_ELEVATION_DEFAULT = false;
|
||||
public static final String STATS_UNITS_DEFAULT = "METRIC";
|
||||
public static final boolean STATS_SHOW_CALORIE_DEFAULT = false;
|
||||
public static final int STATS_WEIGHT_DEFAULT = 65; // in kilogram
|
||||
|
||||
// Track color
|
||||
public static final String TRACK_COLOR_MODE_DEFAULT = "SINGLE";
|
||||
|
||||
@@ -175,8 +175,20 @@ public class StatsUtils {
|
||||
}
|
||||
|
||||
// Set calories
|
||||
double calories = tripStatistics == null ? Double.NaN : tripStatistics.getCalorie();
|
||||
setCalorie(activity, R.id.stats_calorie, R.string.stats_calorie, calories);
|
||||
boolean showCalorie = PreferencesUtils.getBoolean(activity, R.string.stats_show_calorie_key,
|
||||
PreferencesUtils.STATS_SHOW_CALORIE_DEFAULT);
|
||||
View calorieHorizontalLine = activity.findViewById(R.id.stats_calorie_horizontal_line);
|
||||
View calorieContainer = activity.findViewById(R.id.stats_calorie_container);
|
||||
|
||||
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);
|
||||
} else {
|
||||
calorieHorizontalLine.setVisibility(View.GONE);
|
||||
calorieContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,27 +24,33 @@ public class UnitConversions {
|
||||
|
||||
private UnitConversions() {}
|
||||
|
||||
// Milliliter to liter
|
||||
// multiplication factor to convert milliliters to liters
|
||||
public static final double ML_TO_L = 1 / 1000.0;
|
||||
|
||||
// Millisecond to second
|
||||
// multiplication factor to convert milliseconds to seconds
|
||||
public static final double MS_TO_S = 1 / 1000.0;
|
||||
|
||||
// Minute to second
|
||||
// multiplication factor to convert minutes to seconds
|
||||
public static final double MIN_TO_S = 60.0;
|
||||
|
||||
// Second to minute
|
||||
// multiplication factor to convert seconds to minutes
|
||||
public static final double S_TO_MIN = 1 / MIN_TO_S;
|
||||
|
||||
// Minute to hour
|
||||
// multiplication factor to convert hours to minutes
|
||||
public static final double HR_TO_MIN = 60.0;
|
||||
|
||||
// Minute to hour
|
||||
// multiplication factor to convert minutes to hours
|
||||
public static final double MIN_TO_HR = 1 / HR_TO_MIN;
|
||||
|
||||
// multiplication factor to convert kilometers to miles
|
||||
public static final double KM_TO_MI = 0.621371192;
|
||||
|
||||
// multiplication factor to convert kilograms to pounds
|
||||
public static final double KG_TO_LB = 2.2046;
|
||||
|
||||
// multiplication factor to convert pounds to kilograms
|
||||
public static final double LB_TO_KG = 1 / KG_TO_LB;
|
||||
|
||||
// multiplication factor to convert miles to kilometers
|
||||
public static final double MI_TO_KM = 1 / KM_TO_MI;
|
||||
|
||||
@@ -71,6 +77,6 @@ public class UnitConversions {
|
||||
// multiplication factor to convert degrees to radians
|
||||
public static final double DEG_TO_RAD = Math.PI / 180.0;
|
||||
|
||||
// Ratio of change kcal to joule.
|
||||
// multiplication factor to convert Kcal to joules.
|
||||
public static final double KCAL_TO_J = 4.184;
|
||||
}
|
||||
|
||||
+9
-6
@@ -223,8 +223,9 @@ public class TripStatisticsUpdaterTest extends TestCase {
|
||||
// Each time slice is 10 seconds.
|
||||
Location location = getLocation(i + locationOffset, (i + locationOffset) * .001, MOVING_SPEED,
|
||||
startTime + (timeOffset + i) * TEN_SECONDS);
|
||||
tripStatisticsUpdater.addLocation(
|
||||
location, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT);
|
||||
tripStatisticsUpdater.addLocation(location,
|
||||
PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT);
|
||||
tripStatistics = tripStatisticsUpdater.getTripStatistics();
|
||||
|
||||
assertEquals((timeOffset + i) * TEN_SECONDS, tripStatistics.getTotalTime());
|
||||
@@ -269,8 +270,9 @@ public class TripStatisticsUpdaterTest extends TestCase {
|
||||
for (int i = 0; i < points; i++) {
|
||||
Location location = getLocation(
|
||||
locationOffset, locationOffset * .001, 0, startTime + (i + timeOffset) * TEN_SECONDS);
|
||||
tripStatisticsUpdater.addLocation(
|
||||
location, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT);
|
||||
tripStatisticsUpdater.addLocation(location,
|
||||
PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT);
|
||||
|
||||
tripStatistics = tripStatisticsUpdater.getTripStatistics();
|
||||
assertEquals((i + timeOffset) * TEN_SECONDS, tripStatistics.getTotalTime());
|
||||
@@ -306,8 +308,9 @@ public class TripStatisticsUpdaterTest extends TestCase {
|
||||
// 99999 means a speed should bigger than given speed.
|
||||
Location location = getLocation(i + locationOffset, (i + locationOffset) * .001, 99999,
|
||||
startTime + (timeOffset + i) * TEN_SECONDS);
|
||||
tripStatisticsUpdater.addLocation(
|
||||
location, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT);
|
||||
tripStatisticsUpdater.addLocation(location,
|
||||
PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT,
|
||||
PreferencesUtils.STATS_WEIGHT_DEFAULT);
|
||||
tripStatistics = tripStatisticsUpdater.getTripStatistics();
|
||||
|
||||
assertTrue(tripStatistics.getMovingTime() <= tripStatistics.getTotalTime());
|
||||
|
||||
@@ -44,9 +44,9 @@ public class CalorieUtilsTest extends TestCase {
|
||||
* Checks using foot calculation equation.
|
||||
*/
|
||||
public void testGetCalories_foot() {
|
||||
double actual = CalorieUtils.getCalories(start, stop, grade, weight,
|
||||
double actual = CalorieUtils.getCalorie(start, stop, grade, weight,
|
||||
CalorieUtils.ActivityType.FOOT);
|
||||
double expected = CalorieUtils.calculateExpenditureFoot(start, stop, grade, weight);
|
||||
double expected = CalorieUtils.calculateCalorieFoot(start, stop, grade, weight);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@@ -56,9 +56,9 @@ public class CalorieUtilsTest extends TestCase {
|
||||
public void testGetCalories_footNegativeGrade() {
|
||||
double actualGrade = -5;
|
||||
double expectGrade = 0;
|
||||
double actual = CalorieUtils.getCalories(start, stop, actualGrade, weight,
|
||||
double actual = CalorieUtils.getCalorie(start, stop, actualGrade, weight,
|
||||
CalorieUtils.ActivityType.FOOT);
|
||||
double expected = CalorieUtils.calculateExpenditureFoot(start, stop, expectGrade, weight);
|
||||
double expected = CalorieUtils.calculateCalorieFoot(start, stop, expectGrade, weight);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ public class CalorieUtilsTest extends TestCase {
|
||||
* Checks using cycling calculation equation.
|
||||
*/
|
||||
public void testGetCalories_cycling() {
|
||||
double actual = CalorieUtils.getCalories(start, stop, grade, weight,
|
||||
double actual = CalorieUtils.getCalorie(start, stop, grade, weight,
|
||||
CalorieUtils.ActivityType.CYCLING);
|
||||
double expected = CalorieUtils.calculateExpenditureCycling(start, stop, grade, weight);
|
||||
double expected = CalorieUtils.calculateCalorieCycling(start, stop, grade, weight);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ public class CalorieUtilsTest extends TestCase {
|
||||
* Checks using running VO2 equation.
|
||||
*/
|
||||
public void testGetVO2_running() {
|
||||
double actual = CalorieUtils.getVo2(CalorieUtils.CRTICAL_SPEED_RUNNING * 2, grade);
|
||||
double expected = CalorieUtils.calculateRunningVo2(CalorieUtils.CRTICAL_SPEED_RUNNING * 2,
|
||||
double actual = CalorieUtils.getFootVo2(CalorieUtils.CRTICAL_SPEED_RUNNING * 2, grade);
|
||||
double expected = CalorieUtils.getHighSpeedFootVo2(CalorieUtils.CRTICAL_SPEED_RUNNING * 2,
|
||||
grade);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
@@ -89,8 +89,8 @@ public class CalorieUtilsTest extends TestCase {
|
||||
// Test at half the critical speed
|
||||
double footSpeed = CalorieUtils.CRTICAL_SPEED_RUNNING / 2.0;
|
||||
|
||||
double actual = CalorieUtils.getVo2(footSpeed, grade);
|
||||
double expected = CalorieUtils.calculateWalkingVo2(footSpeed, grade);
|
||||
double actual = CalorieUtils.getFootVo2(footSpeed, grade);
|
||||
double expected = CalorieUtils.getLowSpeedFootVo2(footSpeed, grade);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user