diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index 7b2707a67..6a86a0b47 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -42,7 +42,6 @@ limitations under the License. statsRate statsShowCoordinate statsShowGradeElevation - statsShowCalorie statsWeight statsUnits trackColorModeMedium @@ -93,4 +92,5 @@ limitations under the License. settingsSensorBluetoothPairing settingsSensorRoot settingsStats + settingsStatsWeightDisplay \ No newline at end of file diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 9f9a4621a..59c071169 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -2025,16 +2025,12 @@ limitations under the License. Character limit: ~23 (1 line)"> Grade/Elevation - Weight - - Weight for calculating calories. - %1$.1f mi (poor GPS) + + %1$s kg + %1$d kB - - %1$d kg - %1$d %% - - %1$d lb - Off + + %1$s lb + Smallest diff --git a/MyTracks/res/xml/stats_settings.xml b/MyTracks/res/xml/stats_settings.xml index 6366055d7..671787104 100644 --- a/MyTracks/res/xml/stats_settings.xml +++ b/MyTracks/res/xml/stats_settings.xml @@ -24,6 +24,12 @@ limitations under the License. android:defaultValue="@string/stats_rate_speed" android:key="@string/stats_rate_key" android:title="@string/settings_stats_rate_title" /> + - - \ No newline at end of file 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 5e39c3924..21d149661 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -1006,7 +1006,7 @@ public class TrackRecordingService extends Service { Uri uri = myTracksProviderUtils.insertTrackPoint(location, track.getId()); long trackPointId = Long.parseLong(uri.getLastPathSegment()); trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, true, - CalorieUtils.getActivityType(context, track.getCategory()), PreferencesUtils.getInt(context, + CalorieUtils.getActivityType(context, track.getCategory()), PreferencesUtils.getFloat(context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT)); markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval, false, ActivityType.INVALID, PreferencesUtils.STATS_WEIGHT_DEFAULT); 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 1b815ed51..ad3995b6f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/StatsSettingsActivity.java @@ -17,22 +17,21 @@ package com.google.android.apps.mytracks.settings; import com.google.android.apps.mytracks.util.PreferencesUtils; +import com.google.android.apps.mytracks.util.StringUtils; 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; +import android.view.KeyEvent; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; /** * An activity for accessing stats settings. @@ -43,23 +42,19 @@ 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(); + weightPreference = (EditTextPreference) findPreference( + getString(R.string.settings_stats_weight_display_key)); configWeightPreference(); - updateWeightSummary(); + updateWeightSummary(PreferencesUtils.isMetricUnits(this)); + /* * Note configureUnitsListPreference will trigger * configureRateListPreference @@ -67,32 +62,62 @@ public class StatsSettingsActivity extends AbstractSettingsActivity { configUnitsListPreference(); } + /** + * Configures the weight preference. + */ + private void configWeightPreference() { + weightPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + storeWeightValue((String) newValue); + updateWeightSummary(PreferencesUtils.isMetricUnits(StatsSettingsActivity.this)); + return true; + } + }); + + weightPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference pref) { + double value = getWeightDisplayValue( + PreferencesUtils.isMetricUnits(getApplicationContext())); + ((EditTextPreference) pref).getEditText().setText(StringUtils.formatWeight(value)); + return true; + } + }); + weightPreference.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + Dialog dialog = weightPreference.getDialog(); + weightPreference.onClick(dialog, Dialog.BUTTON_POSITIVE); + dialog.dismiss(); + return true; + } + return false; + } + }); + } + /** * Configures the preferred units list preference. */ 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 - 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)); - // Recreate weight value dialog. - removeDialog(WEIGHT_INPUT_DIALOG); - onCreateDialog(WEIGHT_INPUT_DIALOG); - + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + boolean metricUnits = PreferencesUtils.STATS_UNITS_DEFAULT.equals((String) newValue); + configRateListPreference(metricUnits); + updateWeightSummary(metricUnits); + 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); @@ -105,101 +130,23 @@ 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. - */ - 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(getWeightDisplayValue(PreferencesUtils - .isMetricUnits(getApplicationContext())))); - 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. - */ - 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. */ - private void updateWeightSummary() { - boolean metricUnits = PreferencesUtils.isMetricUnits(this); - updateWeightSummary(metricUnits); - } - - /** - * Updates the weight summary. - * - * @param metricUnits true if 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)); + weightPreference.setSummary(getString( + metricUnits ? R.string.value_kilogram : R.string.value_pound, + StringUtils.formatWeight(getWeightDisplayValue(metricUnits)))); } /** @@ -208,11 +155,11 @@ public class StatsSettingsActivity extends AbstractSettingsActivity { * * @param metricUnits true if metric units */ - private int getWeightDisplayValue(boolean metricUnits) { - int value = PreferencesUtils.getInt(this, R.string.stats_weight_key, - PreferencesUtils.STATS_WEIGHT_DEFAULT); + private double getWeightDisplayValue(boolean metricUnits) { + double value = PreferencesUtils.getFloat( + this, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT); if (!metricUnits) { - value = (int) Math.round(value * UnitConversions.KG_TO_LB); + value = value * UnitConversions.KG_TO_LB; } return value; } @@ -223,21 +170,16 @@ public class StatsSettingsActivity extends AbstractSettingsActivity { * @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; + double value; try { - value = Integer.parseInt(displayValue); + value = Double.parseDouble(displayValue); if (!PreferencesUtils.isMetricUnits(this)) { - value = (int) (value * UnitConversions.LB_TO_KG); + value = 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); + PreferencesUtils.setFloat(this, R.string.stats_weight_key, (float) value); } } 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 0e45efe7c..3d9912388 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java +++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsUpdater.java @@ -131,7 +131,7 @@ public class TripStatisticsUpdater { * calorie */ public void addLocation(Location location, int minRecordingDistance, - boolean calculateCalorie, ActivityType activityType, int weight) { + boolean calculateCalorie, ActivityType activityType, double weight) { // Always update time updateTime(location.getTime()); if (!LocationUtils.isValidLocation(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 7c22f5695..3d5b9b6e9 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/CalorieUtils.java @@ -120,11 +120,11 @@ public class CalorieUtils { int recordingDistanceInterval = PreferencesUtils.getInt(context, R.string.recording_distance_interval_key, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT); - int statsWeight = PreferencesUtils.getInt( + double weight = PreferencesUtils.getFloat( context, R.string.stats_weight_key, PreferencesUtils.STATS_WEIGHT_DEFAULT); while (iterator.hasNext()) { tripStatisticsUpdater.addLocation( - iterator.next(), recordingDistanceInterval, true, activityType, statsWeight); + iterator.next(), recordingDistanceInterval, true, activityType, weight); } return tripStatisticsUpdater.getTripStatistics().getCalorie(); } @@ -140,7 +140,7 @@ public class CalorieUtils { * @param activityType the activity type */ public static double getCalorie( - Location start, Location stop, double grade, int weight, ActivityType activityType) { + Location start, Location stop, double grade, double weight, ActivityType activityType) { if (activityType == ActivityType.INVALID) { return 0.0; } @@ -157,7 +157,7 @@ public class CalorieUtils { * @param weight the weight in kilogram of the rider plus bike */ @VisibleForTesting - static double getCyclingCalorie(Location start, Location stop, double grade, int weight) { + static double getCyclingCalorie(Location start, Location stop, double grade, double weight) { // Gets duration in seconds double duration = (double) (stop.getTime() - start.getTime()) * UnitConversions.MS_TO_S; // Get speed in meters per second @@ -191,7 +191,7 @@ public class CalorieUtils { * @param duration the duration in seconds */ @VisibleForTesting - static double getCyclingCalorie(double speed, double grade, int weight, double duration) { + static double getCyclingCalorie(double speed, double grade, double weight, double duration) { // Get the power in watt (Joule/second) double power = EARTH_GRAVITY * weight * speed * (K1 + grade) + K2 * (speed * speed * speed); @@ -208,7 +208,7 @@ public class CalorieUtils { * @param weight the weight of the user in kilogram */ @VisibleForTesting - static double getFootCalorie(Location start, Location stop, double grade, int weight) { + static double getFootCalorie(Location start, Location stop, double grade, double weight) { // Get speed in meters per second double averageSpeed = (start.getSpeed() + stop.getSpeed()) / 2.0; // Get VO2 in mL/kg/min diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java index 10b47cb16..98cf402f2 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java @@ -106,8 +106,7 @@ 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 + public static final float STATS_WEIGHT_DEFAULT = 65.0f; // in kilogram // Track color public static final String TRACK_COLOR_MODE_DEFAULT = "SINGLE"; @@ -194,6 +193,35 @@ public class PreferencesUtils { ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); } + /** + * Gets a float preference value. + * + * @param context the context + * @param keyId the key id + * @param defaultValue the default value + */ + public static float getFloat(Context context, int keyId, float defaultValue) { + SharedPreferences sharedPreferences = context.getSharedPreferences( + Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + return sharedPreferences.getFloat(getKey(context, keyId), defaultValue); + } + + /** + * Sets a float preference value. + * + * @param context the context + * @param keyId the key id + * @param value the value + */ + @SuppressLint("CommitPrefEdits") + public static void setFloat(Context context, int keyId, float value) { + SharedPreferences sharedPreferences = context.getSharedPreferences( + Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + Editor editor = sharedPreferences.edit(); + editor.putFloat(getKey(context, keyId), value); + ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); + } + /** * Gets a long preference value. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java index 1e4aa7744..cac5829d1 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java @@ -148,10 +148,18 @@ public class StringUtils { } } } + + public static String formatWeight(double value) { + return formatDecimal(value, 1); + } public static String formatDecimal(double value) { - String result = String.format(Locale.getDefault(), "%1$,.2f", value); - return result.endsWith(".00") ? result.substring(0, result.lastIndexOf('.')) : result; + return formatDecimal(value, 2); + } + + private static String formatDecimal(double value, int precision) { + String result = String.format(Locale.getDefault(), "%1$,." + precision + "f", value); + return value % 1 == 0 ? result.substring(0, result.lastIndexOf('.')) : result; } /**