Add stats settings to configure the stats page.

This commit is contained in:
Jimmy Shih
2012-04-30 11:22:13 -07:00
parent 20eec8d30a
commit 39a3fb6132
15 changed files with 380 additions and 186 deletions
@@ -19,7 +19,6 @@ 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;
@@ -38,17 +37,8 @@ public class AggregatedStatsActivity extends AbstractMyTracksActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aggregated_stats);
boolean metricUnits = PreferencesUtils.isMetricUnits(this);
boolean reportSpeed = PreferencesUtils.isReportSpeed(this);
StatsUtils.setStats(this,
getTripStatistics(),
null,
Double.NaN,
metricUnits,
reportSpeed,
false);
StatsUtils.setTripStatisticsValues(this, getTripStatistics());
StatsUtils.setLocationValues(this, null, false);
}
/**
@@ -20,7 +20,6 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
@@ -82,17 +81,8 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity {
} else {
waypointSection.setVisibility(View.GONE);
statisticsSection.setVisibility(View.VISIBLE);
boolean metricUnits = PreferencesUtils.isMetricUnits(this);
boolean reportSpeed = PreferencesUtils.isReportSpeed(this);
StatsUtils.setStats(this,
waypoint.getStatistics(),
null,
waypoint.getLocation().getAltitude(),
metricUnits,
reportSpeed,
false);
StatsUtils.setTripStatisticsValues(this, waypoint.getStatistics());
StatsUtils.setLocationValues(this, waypoint.getLocation(), false);
}
}
@@ -27,6 +27,8 @@ import com.google.android.apps.mytracks.fragments.InstallEarthDialogFragment;
import com.google.android.apps.mytracks.fragments.MapFragment;
import com.google.android.apps.mytracks.fragments.MarkerAddDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsFragment;
import com.google.android.apps.mytracks.fragments.StatsSettingsDialogFragment;
import com.google.android.apps.mytracks.fragments.StatsSettingsDialogFragment.OnStatsSettingsChangedListener;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
@@ -63,7 +65,8 @@ import java.util.List;
* @author Leif Hendrik Wilden
* @author Rodrigo Damazio
*/
public class TrackDetailActivity extends AbstractMyTracksActivity {
public class TrackDetailActivity extends AbstractMyTracksActivity
implements OnStatsSettingsChangedListener {
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
@@ -233,6 +236,8 @@ public class TrackDetailActivity extends AbstractMyTracksActivity {
String currentTabTag = tabHost.getCurrentTabTag();
menu.findItem(R.id.track_detail_chart_settings).setVisible(
ChartFragment.CHART_FRAGMENT_TAG.equals(currentTabTag));
menu.findItem(R.id.track_detail_stats_settings).setVisible(
StatsFragment.STATS_FRAGMENT_TAG.equals(currentTabTag));
menu.findItem(R.id.track_detail_my_location)
.setVisible(MapFragment.MAP_FRAGMENT_TAG.equals(currentTabTag));
MenuItem satelliteMode = menu.findItem(R.id.track_detail_satellite_mode)
@@ -352,13 +357,17 @@ public class TrackDetailActivity extends AbstractMyTracksActivity {
mapFragment.setSatelliteView(!mapFragment.isSatelliteView());
}
return true;
case R.id.track_detail_sensor_state:
intent = IntentUtils.newIntent(this, SensorStateActivity.class);
startActivity(intent);
return true;
case R.id.track_detail_chart_settings:
new ChartSettingsDialogFragment().show(
getSupportFragmentManager(), ChartSettingsDialogFragment.CHART_SETTINGS_DIALOG_TAG);
return true;
case R.id.track_detail_sensor_state:
intent = IntentUtils.newIntent(this, SensorStateActivity.class);
startActivity(intent);
case R.id.track_detail_stats_settings:
new StatsSettingsDialogFragment().show(
getSupportFragmentManager(), StatsSettingsDialogFragment.STATS_SETTINGS_DIALOG_TAG);
return true;
case R.id.track_detail_settings:
intent = IntentUtils.newIntent(this, SettingsActivity.class);
@@ -392,6 +401,13 @@ public class TrackDetailActivity extends AbstractMyTracksActivity {
return mapViewContainer;
}
@Override
public void onStatsSettingsChanged() {
StatsFragment statsFragment = (StatsFragment) getSupportFragmentManager()
.findFragmentByTag(StatsFragment.STATS_FRAGMENT_TAG);
statsFragment.updateUi();
}
/**
* Handles the data in the intent.
*/
@@ -55,8 +55,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
// The start time of the current track.
private long startTime = -1L;
private boolean metricUnits = true;
private boolean reportSpeed = true;
private Location lastLocation = null;
private TripStatistics lastTripStatistics = null;
@@ -98,8 +96,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
metricUnits = PreferencesUtils.isMetricUnits(getActivity());
reportSpeed = PreferencesUtils.isReportSpeed(getActivity());
updateUi();
}
@@ -126,7 +122,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void run() {
lastLocation = null;
StatsUtils.setLocationValues(getActivity(), lastLocation, metricUnits, reportSpeed);
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
});
}
@@ -139,7 +135,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
@Override
public void run() {
lastLocation = location;
StatsUtils.setLocationValues(getActivity(), lastLocation, metricUnits, reportSpeed);
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
});
}
@@ -228,7 +224,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
metricUnits = metric;
updateUi();
}
});
@@ -240,7 +235,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
reportSpeed = speed;
updateUi();
}
});
@@ -277,13 +271,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
return trackDataHub != null && trackDataHub.isRecordingSelected();
}
private void updateUi() {
StatsUtils.setStats(getActivity(),
lastTripStatistics,
lastLocation,
Double.NaN,
metricUnits,
reportSpeed,
true);
public void updateUi() {
StatsUtils.setTripStatisticsValues(getActivity(), lastTripStatistics);
StatsUtils.setLocationValues(getActivity(), lastLocation, true);
}
}
@@ -0,0 +1,96 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.fragments;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RadioGroup;
/**
* A DialogFragment to show stats settings.
*
* @author Jimmy Shih
*/
public class StatsSettingsDialogFragment extends DialogFragment {
public static final String STATS_SETTINGS_DIALOG_TAG = "statsSettingsDialog";
public interface OnStatsSettingsChangedListener {
public void onStatsSettingsChanged();
}
private OnStatsSettingsChangedListener listener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnStatsSettingsChangedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnArticleSelectedListener");
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.stats_settings, null);
final RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.stats_settings_time);
boolean totalTime = PreferencesUtils.getBoolean(
getActivity(), R.string.stats_show_total_time_key, true);
radioGroup.check(totalTime ? R.id.stats_settings_total_time : R.id.stats_settings_moving_time);
final CheckBox elevation = (CheckBox) view.findViewById(R.id.stats_settings_elevation);
final CheckBox grade = (CheckBox) view.findViewById(R.id.stats_settings_grade);
final CheckBox coordinate = (CheckBox) view.findViewById(R.id.stats_settings_coordinate);
elevation.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_elevation_key, false));
grade.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_grade_key, false));
coordinate.setChecked(
PreferencesUtils.getBoolean(getActivity(), R.string.stats_show_coordinate_key, false));
return new AlertDialog.Builder(getActivity()).setNegativeButton(R.string.generic_cancel, null)
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PreferencesUtils.setBoolean(getActivity(), R.string.stats_show_total_time_key,
radioGroup.getCheckedRadioButtonId() == R.id.stats_settings_total_time);
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_elevation_key, elevation.isChecked());
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_grade_key, grade.isChecked());
PreferencesUtils.setBoolean(
getActivity(), R.string.stats_show_coordinate_key, coordinate.isChecked());
listener.onStatsSettingsChanged();
}
})
.setTitle(R.string.menu_stats_settings)
.setView(view)
.create();
}
}
@@ -21,6 +21,7 @@ import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.location.Location;
import android.view.View;
import android.widget.TextView;
/**
@@ -32,51 +33,49 @@ public class StatsUtils {
private StatsUtils() {}
/**
* Sets stats.
*
* @param activity the activity
* @param tripStatistics the trip statistics
* @param location the location, needed when showAll is true
* @param elevation the elevation, needed when showAll is false
* @param metricUnits true to display in metric units
* @param reportSpeed true to report speed
* @param showAll true to display all fields
*/
public static void setStats(Activity activity,
TripStatistics tripStatistics,
Location location,
double elevation,
boolean metricUnits,
boolean reportSpeed,
boolean showAll) {
setSpeedLabels(activity, reportSpeed, showAll);
setTripStatisticsValues(activity, tripStatistics, metricUnits, reportSpeed);
if (showAll) {
setLocationValues(activity, location, metricUnits, reportSpeed);
} else {
setAltitudeValue(activity, R.id.stats_elevation_value, elevation, metricUnits);
}
}
/**
* Sets the location values.
*
* @param activity the activity
* @param location the location
* @param metricUnits true to display in metric units
* @param reportSpeed true to report speed
* @param showAll true to show all the fields, false to show only the
* elevation field
*/
public static void setLocationValues(
Activity activity, Location location, boolean metricUnits, boolean reportSpeed) {
public static void setLocationValues(Activity activity, Location location, boolean showAll) {
boolean metricUnits = PreferencesUtils.getBoolean(activity, R.string.metric_units_key, true);
boolean reportSpeed = PreferencesUtils.getBoolean(activity, R.string.report_speed_key, true);
// Set elevation
boolean showElevation = PreferencesUtils.getBoolean(
activity, R.string.stats_show_elevation_key, false);
if (showElevation) {
double altitude = location == null ? Double.NaN : location.getAltitude();
setElevationValue(activity, R.id.stats_elevation_value, altitude, metricUnits);
}
if (!showAll) {
return;
}
// Set speed/pace
setSpeedLabel(
activity, R.id.stats_speed_label, R.string.stats_speed, R.string.stats_pace, reportSpeed);
double speed = location == null ? Double.NaN : location.getSpeed();
double altitude = location == null ? Double.NaN : location.getAltitude();
double latitude = location == null ? Double.NaN : location.getLatitude();
double longitude = location == null ? Double.NaN : location.getLongitude();
setSpeedValue(activity, R.id.stats_speed_value, speed, metricUnits, reportSpeed);
setAltitudeValue(activity, R.id.stats_elevation_value, altitude, metricUnits);
setCoordinateValue(activity, R.id.stats_latitude_value, latitude);
setCoordinateValue(activity, R.id.stats_longitude_value, longitude);
// Set coordinate
boolean showCoordinate = PreferencesUtils.getBoolean(
activity, R.string.stats_show_coordinate_key, false);
View coordinateLabelTableRow = activity.findViewById(R.id.stats_coordinate_label_table_row);
View coordinateValueTableRow = activity.findViewById(R.id.stats_coordinate_value_table_row);
coordinateLabelTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
coordinateValueTableRow.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
if (showCoordinate) {
double latitude = location == null ? Double.NaN : location.getLatitude();
double longitude = location == null ? Double.NaN : location.getLongitude();
setCoordinateValue(activity, R.id.stats_latitude_value, latitude);
setCoordinateValue(activity, R.id.stats_longitude_value, longitude);
}
}
/**
@@ -89,63 +88,104 @@ public class StatsUtils {
setTimeValue(activity, R.id.stats_total_time_value, totalTime);
}
/**
* Sets the speed labels.
*
* @param activity the activity
* @param reportSpeed true to report speed
* @param includeLocationSpeed true to include the current location speed
*/
private static void setSpeedLabels(
Activity activity, boolean reportSpeed, boolean includeLocationSpeed) {
setSpeedLabel(activity, R.id.stats_max_speed_label, R.string.stats_max_speed,
R.string.stats_fastest_pace, reportSpeed);
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_speed,
R.string.stats_average_pace, reportSpeed);
setSpeedLabel(activity, R.id.stats_average_moving_speed_label,
R.string.stats_average_moving_speed, R.string.stats_average_moving_pace, reportSpeed);
if (includeLocationSpeed) {
setSpeedLabel(
activity, R.id.stats_speed_label, R.string.stats_speed, R.string.stats_pace, reportSpeed);
}
}
/**
* Sets the trip statistics values.
*
* @param activity the activity
* @param tripStatistics the trip statistics
* @param metricUnits true to display in metric units
* @param reportSpeed true to report speed
*/
private static void setTripStatisticsValues(
Activity activity, TripStatistics tripStatistics, boolean metricUnits, boolean reportSpeed) {
public static void setTripStatisticsValues(Activity activity, TripStatistics tripStatistics) {
boolean metricUnits = PreferencesUtils.getBoolean(activity, R.string.metric_units_key, true);
boolean reportSpeed = PreferencesUtils.getBoolean(activity, R.string.report_speed_key, true);
boolean showTotalTime = PreferencesUtils.getBoolean(
activity, R.string.stats_show_total_time_key, true);
// Set total distance
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
long totalTime = tripStatistics == null ? -1L : tripStatistics.getTotalTime();
double averageSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getAverageSpeed();
long movingTime = tripStatistics == null ? -1L : tripStatistics.getMovingTime();
double averageMovingSpeed = tripStatistics == null ? Double.NaN
: tripStatistics.getAverageMovingSpeed();
double elevationGain = tripStatistics == null ? Double.NaN
: tripStatistics.getTotalElevationGain();
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
setDistanceValue(activity, R.id.stats_total_distance_value, totalDistance, metricUnits);
setSpeedValue(activity, R.id.stats_max_speed_value, maxSpeed, metricUnits, reportSpeed);
// Set total time/moving time
setTimeLabel(activity, R.id.stats_total_time_label, R.string.stats_total_time,
R.string.stats_moving_time, showTotalTime);
long totalTime;
if (tripStatistics == null) {
totalTime = -1L;
} else {
totalTime = showTotalTime ? tripStatistics.getTotalTime() : tripStatistics.getMovingTime();
}
setTimeValue(activity, R.id.stats_total_time_value, totalTime);
// Set average speed/moving average speed
if (showTotalTime) {
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_speed,
R.string.stats_average_pace, reportSpeed);
} else {
setSpeedLabel(activity, R.id.stats_average_speed_label, R.string.stats_average_moving_speed,
R.string.stats_average_moving_pace, reportSpeed);
}
double averageSpeed;
if (tripStatistics == null) {
averageSpeed = Double.NaN;
} else {
averageSpeed = showTotalTime ? tripStatistics.getAverageSpeed()
: tripStatistics.getAverageMovingSpeed();
}
setSpeedValue(activity, R.id.stats_average_speed_value, averageSpeed, metricUnits, reportSpeed);
setTimeValue(activity, R.id.stats_moving_time_value, movingTime);
setSpeedValue(activity, R.id.stats_average_moving_speed_value, averageMovingSpeed, metricUnits,
reportSpeed);
setAltitudeValue(activity, R.id.stats_elevation_gain_value, elevationGain, metricUnits);
setAltitudeValue(activity, R.id.stats_min_elevation_value, minElevation, metricUnits);
setAltitudeValue(activity, R.id.stats_max_elevation_value, maxElevation, metricUnits);
setGradeValue(activity, R.id.stats_min_grade_value, minGrade);
setGradeValue(activity, R.id.stats_max_grade_value, maxGrade);
// Set max speed
setSpeedLabel(activity, R.id.stats_max_speed_label, R.string.stats_max_speed,
R.string.stats_fastest_pace, reportSpeed);
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
setSpeedValue(activity, R.id.stats_max_speed_value, maxSpeed, metricUnits, reportSpeed);
// Set elevation
boolean showElevation = PreferencesUtils.getBoolean(
activity, R.string.stats_show_elevation_key, false);
View elevationLabelTableRow1 = activity.findViewById(R.id.stats_elevation_label_table_row1);
View elevationValueTableRow1 = activity.findViewById(R.id.stats_elevation_value_table_row1);
View elevationLabelTableRow2 = activity.findViewById(R.id.stats_elevation_label_table_row2);
View elevationValueTableRow2 = activity.findViewById(R.id.stats_elevation_value_table_row2);
elevationLabelTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationValueTableRow1.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationLabelTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
elevationValueTableRow2.setVisibility(showElevation ? View.VISIBLE : View.GONE);
if (showElevation) {
double elevationGain = tripStatistics == null ? Double.NaN
: tripStatistics.getTotalElevationGain();
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
setElevationValue(activity, R.id.stats_elevation_gain_value, elevationGain, metricUnits);
setElevationValue(activity, R.id.stats_min_elevation_value, minElevation, metricUnits);
setElevationValue(activity, R.id.stats_max_elevation_value, maxElevation, metricUnits);
}
// Set grade
boolean showGrade = PreferencesUtils.getBoolean(activity, R.string.stats_show_grade_key, false);
View gradeLabelTableRow = activity.findViewById(R.id.stats_grade_label_table_row);
View gradeValueTableRow = activity.findViewById(R.id.stats_grade_value_table_row);
gradeLabelTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
gradeValueTableRow.setVisibility(showGrade ? View.VISIBLE : View.GONE);
if (showGrade) {
double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
setGradeValue(activity, R.id.stats_min_grade_value, minGrade);
setGradeValue(activity, R.id.stats_max_grade_value, maxGrade);
}
}
/**
* Sets a time label.
*
* @param activity the activity
* @param id the time label resource id
* @param totalTimeId the total time string id
* @param movingTimeId the moving time string id
* @param totalTime true to use total time
*/
private static void setTimeLabel(Activity activity, int id, int totalTimeId, int movingTimeId,
boolean totalTime) {
TextView textView = (TextView) activity.findViewById(id);
textView.setText(totalTime ? totalTimeId : movingTimeId);
}
/**
@@ -243,25 +283,25 @@ public class StatsUtils {
}
/**
* Sets an altitude value.
* Sets an elevation value.
*
* @param activity the activity
* @param id the altitude value resource id
* @param altitude the altitude in meters
* @param id the elevation value resource id
* @param elevation the elevation in meters
* @param metricUnits true to display in metric units
*/
private static void setAltitudeValue(
Activity activity, int id, double altitude, boolean metricUnits) {
private static void setElevationValue(
Activity activity, int id, double elevation, boolean metricUnits) {
TextView textView = (TextView) activity.findViewById(id);
String value;
if (Double.isNaN(altitude) || Double.isInfinite(altitude)) {
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
value = activity.getString(R.string.value_unknown);
} else {
if (metricUnits) {
value = activity.getString(R.string.value_float_meter, altitude);
value = activity.getString(R.string.value_float_meter, elevation);
} else {
altitude *= UnitConversions.M_TO_FT;
value = activity.getString(R.string.value_float_feet, altitude);
elevation *= UnitConversions.M_TO_FT;
value = activity.getString(R.string.value_float_feet, elevation);
}
}
textView.setText(value);