forked from upstream-mirrors/OpenTracks
Refactor StatsFragment.
This commit is contained in:
@@ -55,7 +55,6 @@ import de.dennisguse.opentracks.settings.SettingsActivity;
|
|||||||
import de.dennisguse.opentracks.util.FileUtils;
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
import de.dennisguse.opentracks.util.IntentUtils;
|
import de.dennisguse.opentracks.util.IntentUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.StatsUtils;
|
|
||||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackUtils;
|
import de.dennisguse.opentracks.util.TrackUtils;
|
||||||
|
|
||||||
@@ -434,22 +433,6 @@ public class TrackDetailActivity extends AbstractListActivity implements ChooseA
|
|||||||
return trackDataHub;
|
return trackDataHub;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the track id.
|
|
||||||
*/
|
|
||||||
// TODO Seems to be no used.
|
|
||||||
@Deprecated
|
|
||||||
public long getTrackId() {
|
|
||||||
return trackId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBluetoothHeartRateSensorName(String sensorName) {
|
|
||||||
StatsUtils.setBluetoothHeartRateSensorName(this, sensorName, isRecording());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the data in the intent.
|
|
||||||
*/
|
|
||||||
private void handleIntent(Intent intent) {
|
private void handleIntent(Intent intent) {
|
||||||
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
|
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
|
||||||
long markerId = intent.getLongExtra(EXTRA_MARKER_ID, -1L);
|
long markerId = intent.getLongExtra(EXTRA_MARKER_ID, -1L);
|
||||||
|
|||||||
@@ -20,16 +20,18 @@ import android.location.Location;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
@@ -43,9 +45,11 @@ import de.dennisguse.opentracks.content.Waypoint;
|
|||||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
||||||
import de.dennisguse.opentracks.services.ITrackRecordingService;
|
import de.dennisguse.opentracks.services.ITrackRecordingService;
|
||||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||||
|
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
|
||||||
import de.dennisguse.opentracks.stats.TripStatistics;
|
import de.dennisguse.opentracks.stats.TripStatistics;
|
||||||
import de.dennisguse.opentracks.util.LocationUtils;
|
import de.dennisguse.opentracks.util.LocationUtils;
|
||||||
import de.dennisguse.opentracks.util.StatsUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
import de.dennisguse.opentracks.util.TrackIconUtils;
|
import de.dennisguse.opentracks.util.TrackIconUtils;
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
|
|
||||||
@@ -59,6 +63,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
|
|
||||||
public static final String STATS_FRAGMENT_TAG = StatsFragment.class.getSimpleName();
|
public static final String STATS_FRAGMENT_TAG = StatsFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final long UI_UPDATE_INTERVAL = UnitConversions.ONE_SECOND;
|
||||||
|
|
||||||
private TrackDataHub trackDataHub;
|
private TrackDataHub trackDataHub;
|
||||||
private Handler handlerUpdateUI;
|
private Handler handlerUpdateUI;
|
||||||
|
|
||||||
@@ -67,18 +73,6 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
private Location lastLocation = null;
|
private Location lastLocation = null;
|
||||||
private TripStatistics lastTripStatistics = null;
|
private TripStatistics lastTripStatistics = null;
|
||||||
|
|
||||||
private final Runnable updateUIeachSecond = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
if (isResumed() && isSelectedTrackRecording()) {
|
|
||||||
if (!isSelectedTrackPaused() && lastTripStatistics != null) {
|
|
||||||
StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - lastTripStatistics.getStopTime() + lastTripStatistics.getTotalTime());
|
|
||||||
updateSensorDataUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerUpdateUI.postDelayed(this, UnitConversions.ONE_SECOND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private String category = "";
|
private String category = "";
|
||||||
private int recordingGpsAccuracy;
|
private int recordingGpsAccuracy;
|
||||||
|
|
||||||
@@ -87,6 +81,111 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
return inflater.inflate(R.layout.stats, container, false);
|
return inflater.inflate(R.layout.stats, container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Views */
|
||||||
|
private View sensorContainerView;
|
||||||
|
private TextView heartRateValueView;
|
||||||
|
private TextView heartRateSensorView;
|
||||||
|
|
||||||
|
private TextView totalTimeValueView;
|
||||||
|
private final Runnable updateUIeachSecond = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (isResumed() && isSelectedTrackRecording()) {
|
||||||
|
if (!isSelectedTrackPaused() && lastTripStatistics != null) {
|
||||||
|
setTotalTimeValue(System.currentTimeMillis() - lastTripStatistics.getStopTime() + lastTripStatistics.getTotalTime());
|
||||||
|
updateSensorDataUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerUpdateUI.postDelayed(this, UI_UPDATE_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private TextView distanceValue;
|
||||||
|
private TextView distanceUnit;
|
||||||
|
private View activityLabel;
|
||||||
|
private Spinner activitySpinner;
|
||||||
|
private TextView movingTimeValue;
|
||||||
|
private TextView speedAvgLabel;
|
||||||
|
private TextView speedAvgValue;
|
||||||
|
private TextView speedAvgUnit;
|
||||||
|
private TextView speedMaxLabel;
|
||||||
|
private TextView speedMaxValue;
|
||||||
|
private TextView speedMaxUnit;
|
||||||
|
private TextView speedMovingLabel;
|
||||||
|
private TextView speedMovingValue;
|
||||||
|
private TextView speedMovingUnit;
|
||||||
|
private View gradeElevationSeparator;
|
||||||
|
private View gradeElevationContainer;
|
||||||
|
private TextView elevationMinValue;
|
||||||
|
private TextView elevationMinUnit;
|
||||||
|
private TextView elevationMaxValue;
|
||||||
|
private TextView elevationMaxUnit;
|
||||||
|
private View speedContainer;
|
||||||
|
private TextView speedLabel;
|
||||||
|
private TextView speedValue;
|
||||||
|
private TextView speedUnit;
|
||||||
|
private View elevationContainer;
|
||||||
|
private TextView elevationValue;
|
||||||
|
private TextView elevationUnit;
|
||||||
|
private View coordinateSeparator;
|
||||||
|
private View coordinateContainer;
|
||||||
|
private TextView latitudeValue;
|
||||||
|
private TextView longitudeValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
sensorContainerView = view.findViewById(R.id.stats_sensor_container);
|
||||||
|
heartRateValueView = view.findViewById(R.id.stats_sensor_heart_rate_value);
|
||||||
|
heartRateSensorView = view.findViewById(R.id.stats_sensor_heart_rate_sensor_value);
|
||||||
|
|
||||||
|
totalTimeValueView = view.findViewById(R.id.stats_total_time_value);
|
||||||
|
|
||||||
|
distanceValue = view.findViewById(R.id.stats_distance_value);
|
||||||
|
distanceUnit = view.findViewById(R.id.stats_distance_unit);
|
||||||
|
|
||||||
|
activityLabel = view.findViewById(R.id.stats_activity_type_label);
|
||||||
|
activitySpinner = view.findViewById(R.id.stats_activity_type_icon);
|
||||||
|
|
||||||
|
movingTimeValue = view.findViewById(R.id.stats_moving_time_value);
|
||||||
|
|
||||||
|
speedAvgLabel = view.findViewById(R.id.stats_average_speed_label);
|
||||||
|
speedAvgValue = view.findViewById(R.id.stats_average_speed_value);
|
||||||
|
speedAvgUnit = view.findViewById(R.id.stats_average_speed_unit);
|
||||||
|
|
||||||
|
speedMaxLabel = view.findViewById(R.id.stats_max_speed_label);
|
||||||
|
speedMaxValue = view.findViewById(R.id.stats_max_speed_value);
|
||||||
|
speedMaxUnit = view.findViewById(R.id.stats_max_speed_unit);
|
||||||
|
|
||||||
|
speedMovingLabel = view.findViewById(R.id.stats_moving_speed_label);
|
||||||
|
speedMovingValue = view.findViewById(R.id.stats_moving_speed_value);
|
||||||
|
speedMovingUnit = view.findViewById(R.id.stats_moving_speed_unit);
|
||||||
|
|
||||||
|
gradeElevationSeparator = view.findViewById(R.id.stats_elevation_separator);
|
||||||
|
gradeElevationContainer = view.findViewById(R.id.stats_elevation_container);
|
||||||
|
|
||||||
|
elevationMinValue = view.findViewById(R.id.stats_elevation_min_value);
|
||||||
|
elevationMinUnit = view.findViewById(R.id.stats_elevation_min_unit);
|
||||||
|
|
||||||
|
elevationMaxValue = view.findViewById(R.id.stats_elevation_max_value);
|
||||||
|
elevationMaxUnit = view.findViewById(R.id.stats_elevation_max_unit);
|
||||||
|
|
||||||
|
speedContainer = view.findViewById(R.id.stats_speed);
|
||||||
|
speedLabel = view.findViewById(R.id.stats_speed_label);
|
||||||
|
speedValue = view.findViewById(R.id.stats_speed_value);
|
||||||
|
speedUnit = view.findViewById(R.id.stats_speed_unit);
|
||||||
|
|
||||||
|
elevationContainer = view.findViewById(R.id.stats_elevation);
|
||||||
|
elevationValue = view.findViewById(R.id.stats_elevation_current_value);
|
||||||
|
elevationUnit = view.findViewById(R.id.stats_elevation_current_unit);
|
||||||
|
|
||||||
|
coordinateSeparator = view.findViewById(R.id.stats_coordinate_separator);
|
||||||
|
coordinateContainer = view.findViewById(R.id.stats_coordinate_container);
|
||||||
|
|
||||||
|
latitudeValue = view.findViewById(R.id.stats_latitude_value);
|
||||||
|
longitudeValue = view.findViewById(R.id.stats_longitude_value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
@@ -125,7 +224,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(getContext(), null);
|
trackRecordingServiceConnection = new TrackRecordingServiceConnection(getContext(), null);
|
||||||
trackRecordingServiceConnection.startConnection(getContext());
|
trackRecordingServiceConnection.startConnection(getContext());
|
||||||
|
|
||||||
updateUi(getActivity());
|
updateUi();
|
||||||
if (isSelectedTrackRecording()) {
|
if (isSelectedTrackRecording()) {
|
||||||
handlerUpdateUI.post(updateUIeachSecond);
|
handlerUpdateUI.post(updateUIeachSecond);
|
||||||
}
|
}
|
||||||
@@ -145,6 +244,60 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
trackRecordingServiceConnection = null;
|
trackRecordingServiceConnection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
sensorContainerView = null;
|
||||||
|
heartRateValueView = null;
|
||||||
|
heartRateSensorView = null;
|
||||||
|
|
||||||
|
totalTimeValueView = null;
|
||||||
|
|
||||||
|
distanceValue = null;
|
||||||
|
distanceUnit = null;
|
||||||
|
|
||||||
|
activityLabel = null;
|
||||||
|
activitySpinner = null;
|
||||||
|
|
||||||
|
movingTimeValue = null;
|
||||||
|
|
||||||
|
speedAvgLabel = null;
|
||||||
|
speedAvgValue = null;
|
||||||
|
speedAvgUnit = null;
|
||||||
|
|
||||||
|
speedMaxLabel = null;
|
||||||
|
speedMaxValue = null;
|
||||||
|
speedMaxUnit = null;
|
||||||
|
|
||||||
|
speedMovingLabel = null;
|
||||||
|
speedMovingValue = null;
|
||||||
|
speedMovingUnit = null;
|
||||||
|
|
||||||
|
gradeElevationSeparator = null;
|
||||||
|
gradeElevationContainer = null;
|
||||||
|
|
||||||
|
elevationMinValue = null;
|
||||||
|
elevationMinUnit = null;
|
||||||
|
|
||||||
|
elevationMaxValue = null;
|
||||||
|
elevationMaxUnit = null;
|
||||||
|
|
||||||
|
speedContainer = null;
|
||||||
|
speedLabel = null;
|
||||||
|
speedValue = null;
|
||||||
|
speedUnit = null;
|
||||||
|
|
||||||
|
elevationContainer = null;
|
||||||
|
elevationValue = null;
|
||||||
|
elevationUnit = null;
|
||||||
|
|
||||||
|
coordinateSeparator = null;
|
||||||
|
coordinateContainer = null;
|
||||||
|
|
||||||
|
latitudeValue = null;
|
||||||
|
longitudeValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTrackUpdated(final Track track) {
|
public void onTrackUpdated(final Track track) {
|
||||||
if (isResumed()) {
|
if (isResumed()) {
|
||||||
@@ -154,7 +307,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
if (isResumed()) {
|
if (isResumed()) {
|
||||||
lastTripStatistics = track != null ? track.getTripStatistics() : null;
|
lastTripStatistics = track != null ? track.getTripStatistics() : null;
|
||||||
category = track != null ? track.getCategory() : "";
|
category = track != null ? track.getCategory() : "";
|
||||||
updateUi(getActivity());
|
updateUi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -195,7 +348,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
lastLocation = null;
|
lastLocation = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatsUtils.setLocationValues(getActivity(), lastLocation, isSelectedTrackRecording());
|
setLocationValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -224,7 +377,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (isResumed()) {
|
if (isResumed()) {
|
||||||
updateUi(getActivity());
|
updateUi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -239,7 +392,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (isResumed()) {
|
if (isResumed()) {
|
||||||
updateUi(getActivity());
|
updateUi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -295,6 +448,12 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
return trackDataHub != null && trackDataHub.isSelectedTrackPaused();
|
return trackDataHub != null && trackDataHub.isSelectedTrackPaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateUi() {
|
||||||
|
updateStats();
|
||||||
|
setLocationValues();
|
||||||
|
updateSensorDataUI();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to fetch most recent {@link SensorDataSet} {@link de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager}.
|
* Tries to fetch most recent {@link SensorDataSet} {@link de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager}.
|
||||||
*/
|
*/
|
||||||
@@ -309,16 +468,173 @@ public class StatsFragment extends Fragment implements TrackDataListener {
|
|||||||
sensorDataSet = trackRecordingService.getSensorData();
|
sensorDataSet = trackRecordingService.getSensorData();
|
||||||
}
|
}
|
||||||
|
|
||||||
StatsUtils.setSensorData(getActivity(), sensorDataSet, isSelectedTrackRecording());
|
setHeartRateSensorData(sensorDataSet, isSelectedTrackRecording());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void setHeartRateSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
|
||||||
* Updates the UI.
|
// heart rate
|
||||||
*/
|
int isVisible = View.VISIBLE;
|
||||||
private void updateUi(FragmentActivity activity) {
|
if (!isRecording || PreferencesUtils.isBluetoothHeartRateSensorAddressDefault(getContext())) {
|
||||||
String trackIconValue = TrackIconUtils.getIconValue(activity, category);
|
isVisible = View.INVISIBLE;
|
||||||
StatsUtils.setTripStatisticsValues(activity, lastTripStatistics, trackIconValue);
|
}
|
||||||
StatsUtils.setLocationValues(activity, lastLocation, isSelectedTrackRecording());
|
sensorContainerView.setVisibility(isVisible);
|
||||||
updateSensorDataUI();
|
|
||||||
|
if (isRecording) {
|
||||||
|
String heartRate = getContext().getString(R.string.value_unknown);
|
||||||
|
String sensorName = getContext().getString(R.string.value_unknown);
|
||||||
|
if (sensorDataSet != null && sensorDataSet.isRecent(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE_MS)) {
|
||||||
|
sensorName = sensorDataSet.getSensorName();
|
||||||
|
if (sensorDataSet.hasHeartRate()) {
|
||||||
|
heartRate = StringUtils.formatDecimal(sensorDataSet.getHeartRate(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heartRateSensorView.setText(sensorName);
|
||||||
|
heartRateValueView.setText(heartRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStats() {
|
||||||
|
String trackIconValue = TrackIconUtils.getIconValue(getContext(), category);
|
||||||
|
|
||||||
|
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||||
|
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext());
|
||||||
|
boolean isRecording = isSelectedTrackRecording();
|
||||||
|
|
||||||
|
// Set total distance
|
||||||
|
{
|
||||||
|
double totalDistance = lastTripStatistics == null ? Double.NaN : lastTripStatistics.getTotalDistance();
|
||||||
|
Pair<String, String> parts = StringUtils.getDistanceParts(getContext(), totalDistance, metricUnits);
|
||||||
|
|
||||||
|
distanceValue.setText(parts.first);
|
||||||
|
distanceUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set activity type
|
||||||
|
{
|
||||||
|
activityLabel.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
activitySpinner.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
||||||
|
activitySpinner.setEnabled(isRecording);
|
||||||
|
if (trackIconValue != null) {
|
||||||
|
TrackIconUtils.setIconSpinner(activitySpinner, trackIconValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set time
|
||||||
|
if (lastTripStatistics != null) {
|
||||||
|
setTotalTimeValue(lastTripStatistics.getTotalTime());
|
||||||
|
|
||||||
|
movingTimeValue.setText(StringUtils.formatElapsedTime(lastTripStatistics.getMovingTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set average speed/pace
|
||||||
|
{
|
||||||
|
double speed = lastTripStatistics != null ? lastTripStatistics.getAverageSpeed() : Double.NaN;
|
||||||
|
speedAvgLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
|
||||||
|
|
||||||
|
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||||
|
speedAvgValue.setText(parts.first);
|
||||||
|
speedAvgUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set max speed/pace
|
||||||
|
{
|
||||||
|
double speed = lastTripStatistics == null ? Double.NaN : lastTripStatistics.getMaxSpeed();
|
||||||
|
|
||||||
|
speedMaxLabel.setText(reportSpeed ? R.string.stats_max_speed : R.string.stats_fastest_pace);
|
||||||
|
|
||||||
|
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||||
|
speedMaxValue.setText(parts.first);
|
||||||
|
speedMaxUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set moving speed/pace
|
||||||
|
{
|
||||||
|
double speed = lastTripStatistics != null ? lastTripStatistics.getAverageMovingSpeed() : Double.NaN;
|
||||||
|
|
||||||
|
speedMovingLabel.setText(reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
|
||||||
|
|
||||||
|
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||||
|
speedMovingValue.setText(parts.first);
|
||||||
|
speedMovingUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set elevation
|
||||||
|
{
|
||||||
|
boolean showElevation = PreferencesUtils.isShowStatsGradeElevation(getContext());
|
||||||
|
gradeElevationSeparator.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
gradeElevationContainer.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
if (showElevation) {
|
||||||
|
{
|
||||||
|
double elevation = lastTripStatistics == null ? Double.NaN : lastTripStatistics.getMinElevation();
|
||||||
|
Pair<String, String> parts = StringUtils.formatElevation(getContext(), elevation, metricUnits);
|
||||||
|
|
||||||
|
|
||||||
|
elevationMinValue.setText(parts.first);
|
||||||
|
elevationMinUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
double elevation = lastTripStatistics == null ? Double.NaN : lastTripStatistics.getMaxElevation();
|
||||||
|
Pair<String, String> parts = StringUtils.formatElevation(getContext(), elevation, metricUnits);
|
||||||
|
|
||||||
|
|
||||||
|
elevationMaxValue.setText(parts.first);
|
||||||
|
elevationMaxUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTotalTimeValue(long totalTime) {
|
||||||
|
totalTimeValueView.setText(StringUtils.formatElapsedTime(totalTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLocationValues() {
|
||||||
|
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext());
|
||||||
|
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext());
|
||||||
|
boolean isRecording = isSelectedTrackRecording();
|
||||||
|
|
||||||
|
// Set speed/pace
|
||||||
|
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
if (isRecording) {
|
||||||
|
speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
||||||
|
|
||||||
|
double speed = lastLocation != null && lastLocation.hasSpeed() ? lastLocation.getSpeed() : Double.NaN;
|
||||||
|
Pair<String, String> parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed);
|
||||||
|
speedValue.setText(parts.first);
|
||||||
|
speedUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set elevation
|
||||||
|
boolean showGradeElevation = isRecording && PreferencesUtils.isShowStatsGradeElevation(getContext());
|
||||||
|
elevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
if (showGradeElevation) {
|
||||||
|
double altitude = lastLocation != null && lastLocation.hasAltitude() ? lastLocation.getAltitude() : Double.NaN;
|
||||||
|
Pair<String, String> parts = StringUtils.formatElevation(getContext(), altitude, metricUnits);
|
||||||
|
|
||||||
|
elevationValue.setText(parts.first);
|
||||||
|
elevationUnit.setText(parts.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set coordinate
|
||||||
|
boolean showCoordinate = isRecording && PreferencesUtils.isStatsShowCoordinate(getContext());
|
||||||
|
|
||||||
|
coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
||||||
|
coordinateContainer.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
||||||
|
if (showCoordinate) {
|
||||||
|
double latitude = lastLocation != null ? lastLocation.getLatitude() : Double.NaN;
|
||||||
|
String latitudeText = Double.isNaN(latitude) || Double.isInfinite(latitude) ? getContext().getString(R.string.value_unknown) : StringUtils.formatCoordinate(latitude);
|
||||||
|
latitudeValue.setText(latitudeText);
|
||||||
|
|
||||||
|
double longitude = lastLocation != null ? lastLocation.getLongitude() : Double.NaN;
|
||||||
|
String longitudeText = Double.isNaN(longitude) || Double.isInfinite(longitude) ? getContext().getString(R.string.value_unknown) : StringUtils.formatCoordinate(longitude);
|
||||||
|
longitudeValue.setText(longitudeText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,282 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 de.dennisguse.opentracks.util;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.location.Location;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
|
||||||
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
|
|
||||||
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
|
|
||||||
import de.dennisguse.opentracks.stats.TripStatistics;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utilities for updating the statistics UI labels and values.
|
|
||||||
*
|
|
||||||
* @author Jimmy Shih
|
|
||||||
*/
|
|
||||||
public class StatsUtils {
|
|
||||||
|
|
||||||
private static final String GRADE_PERCENTAGE = "%";
|
|
||||||
private static final String GRADE_FORMAT = "%1$d";
|
|
||||||
|
|
||||||
private StatsUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the location values.
|
|
||||||
*
|
|
||||||
* @param activity the activity for finding views
|
|
||||||
* @param location the location
|
|
||||||
* @param isRecording true if recording
|
|
||||||
*/
|
|
||||||
public static void setLocationValues(Activity activity, Location location, boolean isRecording) {
|
|
||||||
boolean metricUnits = PreferencesUtils.isMetricUnits(activity);
|
|
||||||
boolean reportSpeed = PreferencesUtils.isReportSpeed(activity);
|
|
||||||
|
|
||||||
// Set speed/pace
|
|
||||||
View speedContainer = activity.findViewById(R.id.stats_speed);
|
|
||||||
speedContainer.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
|
||||||
if (isRecording) {
|
|
||||||
TextView speedLabel = activity.findViewById(R.id.stats_speed_label);
|
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
|
||||||
|
|
||||||
double speed = location != null && location.hasSpeed() ? location.getSpeed() : Double.NaN;
|
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
|
|
||||||
|
|
||||||
TextView speedValue = activity.findViewById(R.id.stats_speed_value);
|
|
||||||
speedValue.setText(parts.first);
|
|
||||||
|
|
||||||
TextView speedUnit = activity.findViewById(R.id.stats_speed_unit);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set elevation
|
|
||||||
boolean showGradeElevation = isRecording && PreferencesUtils.isShowStatsGradeElevation(activity);
|
|
||||||
View elevationContainer = activity.findViewById(R.id.stats_elevation);
|
|
||||||
elevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
if (showGradeElevation) {
|
|
||||||
double altitude = location != null && location.hasAltitude() ? location.getAltitude() : Double.NaN;
|
|
||||||
Pair<String, String> parts = StringUtils.formatElevation(activity, altitude, metricUnits);
|
|
||||||
|
|
||||||
TextView elevationValue = activity.findViewById(R.id.stats_elevation_current_value);
|
|
||||||
elevationValue.setText(parts.first);
|
|
||||||
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_current_unit);
|
|
||||||
elevationUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set coordinate
|
|
||||||
boolean showCoordinate = isRecording && PreferencesUtils.isStatsShowCoordinate(activity);
|
|
||||||
|
|
||||||
View coordinateSeparator = activity.findViewById(R.id.stats_coordinate_separator);
|
|
||||||
coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
View coordinateContainer = activity.findViewById(R.id.stats_coordinate_container);
|
|
||||||
coordinateContainer.setVisibility(showCoordinate ? View.VISIBLE : View.GONE);
|
|
||||||
if (showCoordinate) {
|
|
||||||
double latitude = location != null ? location.getLatitude() : Double.NaN;
|
|
||||||
String latitudeText = Double.isNaN(latitude) || Double.isInfinite(latitude) ? activity.getString(R.string.value_unknown) : StringUtils.formatCoordinate(latitude);
|
|
||||||
TextView latitudeValue = activity.findViewById(R.id.stats_latitude_value);
|
|
||||||
latitudeValue.setText(latitudeText);
|
|
||||||
|
|
||||||
double longitude = location != null ? location.getLongitude() : Double.NaN;
|
|
||||||
String longitudeText = Double.isNaN(longitude) || Double.isInfinite(longitude) ? activity.getString(R.string.value_unknown) : StringUtils.formatCoordinate(longitude);
|
|
||||||
TextView longitudeValue = activity.findViewById(R.id.stats_longitude_value);
|
|
||||||
longitudeValue.setText(longitudeText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setSensorData(Activity activity, SensorDataSet sensorDataSet, boolean isRecording) {
|
|
||||||
// heart rate
|
|
||||||
int isVisible = View.VISIBLE;
|
|
||||||
if (!isRecording || PreferencesUtils.isBluetoothHeartRateSensorAddressDefault(activity)) {
|
|
||||||
isVisible = View.INVISIBLE;
|
|
||||||
}
|
|
||||||
activity.findViewById(R.id.stats_sensor_container).setVisibility(isVisible);
|
|
||||||
|
|
||||||
if (isRecording) {
|
|
||||||
TextView heartRateValue = activity.findViewById(R.id.stats_sensor_heart_rate_value);
|
|
||||||
String heartRate = activity.getString(R.string.value_unknown);
|
|
||||||
String sensor = activity.getString(R.string.value_unknown);
|
|
||||||
if (sensorDataSet != null && sensorDataSet.isRecent(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE_MS)) {
|
|
||||||
sensor = sensorDataSet.getSensorName();
|
|
||||||
if (sensorDataSet.hasHeartRate()) {
|
|
||||||
heartRate = StringUtils.formatDecimal(sensorDataSet.getHeartRate(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setBluetoothHeartRateSensorName(activity, sensor, isRecording);
|
|
||||||
heartRateValue.setText(heartRate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setBluetoothHeartRateSensorName(Activity activity, String sensorName, boolean isRecording) {
|
|
||||||
if (isRecording) {
|
|
||||||
TextView heartRateSensor = activity.findViewById(R.id.stats_sensor_heart_rate_sensor_value);
|
|
||||||
heartRateSensor.setText(sensorName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the total time value.
|
|
||||||
*
|
|
||||||
* @param activity the activity
|
|
||||||
* @param totalTime the total time
|
|
||||||
*/
|
|
||||||
public static void setTotalTimeValue(Activity activity, long totalTime) {
|
|
||||||
TextView totalTimeValue = activity.findViewById(R.id.stats_total_time_value);
|
|
||||||
totalTimeValue.setText(StringUtils.formatElapsedTime(totalTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the trip statistics values.
|
|
||||||
*
|
|
||||||
* @param activity the activity for finding views
|
|
||||||
* @param tripStatistics the trip statistics
|
|
||||||
* @param trackIconValue the track icon value or null to hide the track icon spinner
|
|
||||||
*/
|
|
||||||
public static void setTripStatisticsValues(Activity activity, TripStatistics tripStatistics, String trackIconValue) {
|
|
||||||
boolean metricUnits = PreferencesUtils.isMetricUnits(activity);
|
|
||||||
boolean reportSpeed = PreferencesUtils.isReportSpeed(activity);
|
|
||||||
boolean isRecording = PreferencesUtils.isRecording(activity);
|
|
||||||
|
|
||||||
// Set total distance
|
|
||||||
{
|
|
||||||
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
|
|
||||||
Pair<String, String> parts = StringUtils.getDistanceParts(activity, totalDistance, metricUnits);
|
|
||||||
|
|
||||||
TextView distanceValue = activity.findViewById(R.id.stats_distance_value);
|
|
||||||
distanceValue.setText(parts.first);
|
|
||||||
|
|
||||||
TextView distanceUnit = activity.findViewById(R.id.stats_distance_unit);
|
|
||||||
distanceUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set activity type
|
|
||||||
{
|
|
||||||
activity.findViewById(R.id.stats_activity_type_label).setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
Spinner spinner = activity.findViewById(R.id.stats_activity_type_icon);
|
|
||||||
spinner.setVisibility(trackIconValue != null ? View.VISIBLE : View.GONE);
|
|
||||||
if (trackIconValue != null) {
|
|
||||||
TrackIconUtils.setIconSpinner(spinner, trackIconValue);
|
|
||||||
}
|
|
||||||
spinner.setEnabled(isRecording);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set time
|
|
||||||
if (tripStatistics != null) {
|
|
||||||
setTotalTimeValue(activity, tripStatistics.getTotalTime());
|
|
||||||
|
|
||||||
TextView movingTimeValue = activity.findViewById(R.id.stats_moving_time_value);
|
|
||||||
movingTimeValue.setText(StringUtils.formatElapsedTime(tripStatistics.getMovingTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set average speed/pace
|
|
||||||
{
|
|
||||||
double speed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
|
|
||||||
TextView speedLabel = activity.findViewById(R.id.stats_average_speed_label);
|
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
|
|
||||||
|
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
|
|
||||||
TextView speedValue = activity.findViewById(R.id.stats_average_speed_value);
|
|
||||||
speedValue.setText(parts.first);
|
|
||||||
TextView speedUnit = activity.findViewById(R.id.stats_average_speed_unit);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set max speed/pace
|
|
||||||
{
|
|
||||||
double speed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
|
|
||||||
|
|
||||||
TextView speedLabel = activity.findViewById(R.id.stats_max_speed_label);
|
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_max_speed : R.string.stats_fastest_pace);
|
|
||||||
|
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
|
|
||||||
TextView speedValue = activity.findViewById(R.id.stats_max_speed_value);
|
|
||||||
speedValue.setText(parts.first);
|
|
||||||
TextView speedUnit = activity.findViewById(R.id.stats_max_speed_unit);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set average speed/pace
|
|
||||||
{
|
|
||||||
double speed = tripStatistics != null ? tripStatistics.getAverageSpeed() : Double.NaN;
|
|
||||||
|
|
||||||
TextView speedLabel = activity.findViewById(R.id.stats_average_speed_label);
|
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
|
|
||||||
|
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
|
|
||||||
TextView speedValue = activity.findViewById(R.id.stats_average_speed_value);
|
|
||||||
speedValue.setText(parts.first);
|
|
||||||
TextView speedUnit = activity.findViewById(R.id.stats_average_speed_unit);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set moving speed/pace
|
|
||||||
{
|
|
||||||
double speed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed() : Double.NaN;
|
|
||||||
|
|
||||||
TextView speedLabel = activity.findViewById(R.id.stats_moving_speed_label);
|
|
||||||
speedLabel.setText(reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
|
|
||||||
|
|
||||||
Pair<String, String> parts = StringUtils.getSpeedParts(activity, speed, metricUnits, reportSpeed);
|
|
||||||
TextView speedValue = activity.findViewById(R.id.stats_moving_speed_value);
|
|
||||||
speedValue.setText(parts.first);
|
|
||||||
TextView speedUnit = activity.findViewById(R.id.stats_moving_speed_unit);
|
|
||||||
speedUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set elevation
|
|
||||||
{
|
|
||||||
boolean showElevation = PreferencesUtils.isShowStatsGradeElevation(activity);
|
|
||||||
View gradeElevationSeparator = activity.findViewById(R.id.stats_elevation_separator);
|
|
||||||
gradeElevationSeparator.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
View gradeElevationContainer = activity.findViewById(R.id.stats_elevation_container);
|
|
||||||
gradeElevationContainer.setVisibility(showElevation ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
if (showElevation) {
|
|
||||||
{
|
|
||||||
double elevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
|
|
||||||
Pair<String, String> parts = StringUtils.formatElevation(activity, elevation, metricUnits);
|
|
||||||
|
|
||||||
TextView elevationValue = activity.findViewById(R.id.stats_elevation_min_value);
|
|
||||||
elevationValue.setText(parts.first);
|
|
||||||
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_min_unit);
|
|
||||||
elevationUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
double elevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
|
|
||||||
Pair<String, String> parts = StringUtils.formatElevation(activity, elevation, metricUnits);
|
|
||||||
|
|
||||||
TextView elevationValue = activity.findViewById(R.id.stats_elevation_max_value);
|
|
||||||
elevationValue.setText(parts.first);
|
|
||||||
TextView elevationUnit = activity.findViewById(R.id.stats_elevation_max_unit);
|
|
||||||
elevationUnit.setText(parts.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -132,7 +132,7 @@ public class StringUtils {
|
|||||||
/**
|
/**
|
||||||
* Format a decimal number while removing trailing zeros of the decimal part (if present).
|
* Format a decimal number while removing trailing zeros of the decimal part (if present).
|
||||||
*/
|
*/
|
||||||
static String formatDecimal(double value, int decimalPlaces) {
|
public static String formatDecimal(double value, int decimalPlaces) {
|
||||||
if (decimalPlaces < 1) {
|
if (decimalPlaces < 1) {
|
||||||
return Long.toString(Math.round(value));
|
return Long.toString(Math.round(value));
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ public class StringUtils {
|
|||||||
* @param metricUnits true to use metric unit
|
* @param metricUnits true to use metric unit
|
||||||
* @return the formatted distance (or null) and it's unit as {@link Pair}
|
* @return the formatted distance (or null) and it's unit as {@link Pair}
|
||||||
*/
|
*/
|
||||||
static Pair<String, String> getDistanceParts(Context context, double distance, boolean metricUnits) {
|
public static Pair<String, String> getDistanceParts(Context context, double distance, boolean metricUnits) {
|
||||||
if (Double.isNaN(distance) || Double.isInfinite(distance)) {
|
if (Double.isNaN(distance) || Double.isInfinite(distance)) {
|
||||||
return new Pair<>(null, context.getString(metricUnits ? R.string.unit_meter : R.string.unit_feet));
|
return new Pair<>(null, context.getString(metricUnits ? R.string.unit_meter : R.string.unit_feet));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -363,7 +363,6 @@ limitations under the License.
|
|||||||
<LinearLayout style="@style/StatsLargeItemContainer">
|
<LinearLayout style="@style/StatsLargeItemContainer">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stats_sensor_heart_rate_label"
|
|
||||||
style="@style/StatsLargeLabel"
|
style="@style/StatsLargeLabel"
|
||||||
android:text="@string/sensor_state_heart_rate" />
|
android:text="@string/sensor_state_heart_rate" />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user