Code cleanup.

This commit is contained in:
Dennis Guse
2019-07-11 23:53:08 +02:00
parent 71c2bcbd0c
commit b56f20f0c2
14 changed files with 114 additions and 206 deletions
@@ -29,9 +29,6 @@ import com.google.android.apps.mytracks.util.UnitConversions;
*/ */
public class DeleteAsyncTask extends AsyncTask<Void, Integer, Boolean> { public class DeleteAsyncTask extends AsyncTask<Void, Integer, Boolean> {
// 1 second in milliseconds
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
private DeleteActivity deleteActivity; private DeleteActivity deleteActivity;
private final long[] trackIds; private final long[] trackIds;
private final Context context; private final Context context;
@@ -43,9 +43,6 @@ public class SensorStateActivity extends AbstractActivity {
private static final String TAG = SensorStateActivity.class.getName(); private static final String TAG = SensorStateActivity.class.getName();
// 1 second in milliseconds
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
private TrackRecordingServiceConnection trackRecordingServiceConnection; private TrackRecordingServiceConnection trackRecordingServiceConnection;
private Handler handler; private Handler handler;
private SensorManager tempSensorManager; private SensorManager tempSensorManager;
@@ -53,8 +50,7 @@ public class SensorStateActivity extends AbstractActivity {
private final Runnable updateUiRunnable = new Runnable() { private final Runnable updateUiRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
.getServiceIfBound();
// Check if service is available and recording // Check if service is available and recording
boolean isRecording = false; boolean isRecording = false;
@@ -72,7 +68,7 @@ public class SensorStateActivity extends AbstractActivity {
stopTempSensorManager(); stopTempSensorManager();
updateFromSystemSensorManager(); updateFromSystemSensorManager();
} }
handler.postDelayed(this, ONE_SECOND); handler.postDelayed(this, UnitConversions.ONE_SECOND);
} }
}; };
@@ -149,12 +145,11 @@ public class SensorStateActivity extends AbstractActivity {
Sensor.SensorState sensorState = Sensor.SensorState.NONE; Sensor.SensorState sensorState = Sensor.SensorState.NONE;
Sensor.SensorDataSet sensorDataSet = null; Sensor.SensorDataSet sensorDataSet = null;
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
.getServiceIfBound();
// Get sensor details from the service. // Get sensor details from the service.
if (trackRecordingService == null) { if (trackRecordingService == null) {
Log.d(TAG, "Cannot get teh track recording service."); Log.d(TAG, "Cannot get the track recording service.");
} else { } else {
try { try {
sensorState = Sensor.SensorState.valueOf(trackRecordingService.getSensorState()); sensorState = Sensor.SensorState.valueOf(trackRecordingService.getSensorState());
@@ -184,21 +179,14 @@ public class SensorStateActivity extends AbstractActivity {
* @param sensorState sensor state * @param sensorState sensor state
* @param sensorDataSet sensor data set * @param sensorDataSet sensor data set
*/ */
private void updateSensorStateAndDataSet( private void updateSensorStateAndDataSet(Sensor.SensorState sensorState, Sensor.SensorDataSet sensorDataSet) {
Sensor.SensorState sensorState, Sensor.SensorDataSet sensorDataSet) { ((TextView) findViewById(R.id.sensor_state)).setText(SensorUtils.getStateAsString(sensorState, this));
((TextView) findViewById(R.id.sensor_state)).setText(
SensorUtils.getStateAsString(sensorState, this));
String lastSensorTime = sensorDataSet == null ? getString(R.string.value_unknown) String lastSensorTime = sensorDataSet == null ? getString(R.string.value_unknown) : getLastSensorTime(sensorDataSet);
: getLastSensorTime(sensorDataSet); String heartRate = sensorDataSet == null ? getString(R.string.value_unknown) : getHeartRate(sensorDataSet);
String heartRate = sensorDataSet == null ? getString(R.string.value_unknown) String cadence = sensorDataSet == null ? getString(R.string.value_unknown) : getCadence(sensorDataSet);
: getHeartRate(sensorDataSet); String power = sensorDataSet == null ? getString(R.string.value_unknown) : getPower(sensorDataSet);
String cadence = sensorDataSet == null ? getString(R.string.value_unknown) String battery = sensorDataSet == null ? getString(R.string.value_unknown) : getBattery(sensorDataSet);
: getCadence(sensorDataSet);
String power = sensorDataSet == null ? getString(R.string.value_unknown)
: getPower(sensorDataSet);
String battery = sensorDataSet == null ? getString(R.string.value_unknown)
: getBattery(sensorDataSet);
((TextView) findViewById(R.id.sensor_state_last_sensor_time)).setText(lastSensorTime); ((TextView) findViewById(R.id.sensor_state_last_sensor_time)).setText(lastSensorTime);
((TextView) findViewById(R.id.sensor_state_heart_rate)).setText(heartRate); ((TextView) findViewById(R.id.sensor_state_heart_rate)).setText(heartRate);
@@ -223,14 +211,11 @@ public class SensorStateActivity extends AbstractActivity {
*/ */
private String getHeartRate(Sensor.SensorDataSet sensorDataSet) { private String getHeartRate(Sensor.SensorDataSet sensorDataSet) {
String value; String value;
if (sensorDataSet.hasHeartRate() && sensorDataSet.getHeartRate().hasValue() if (sensorDataSet.hasHeartRate() && sensorDataSet.getHeartRate().hasValue() && sensorDataSet.getHeartRate().getState() == Sensor.SensorState.SENDING) {
&& sensorDataSet.getHeartRate().getState() == Sensor.SensorState.SENDING) {
value = getString( value = getString(
R.string.sensor_state_heart_rate_value, sensorDataSet.getHeartRate().getValue()); R.string.sensor_state_heart_rate_value, sensorDataSet.getHeartRate().getValue());
} else { } else {
value = SensorUtils.getStateAsString( value = SensorUtils.getStateAsString(sensorDataSet.hasHeartRate() ? sensorDataSet.getHeartRate().getState() : Sensor.SensorState.NONE, this);
sensorDataSet.hasHeartRate() ? sensorDataSet.getHeartRate().getState()
: Sensor.SensorState.NONE, this);
} }
return value; return value;
} }
@@ -39,13 +39,10 @@ import android.widget.TextView;
public class TrackController { public class TrackController {
private static final String TAG = TrackController.class.getSimpleName(); private static final String TAG = TrackController.class.getSimpleName();
// 1 second in milliseconds
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
private final Activity activity; private final Activity activity;
private final TrackRecordingServiceConnection trackRecordingServiceConnection; private final TrackRecordingServiceConnection trackRecordingServiceConnection;
private final Handler handler; private final Handler handlerUpdateTotalTime;
private final View containerView; private final View containerView;
private final TextView statusTextView; private final TextView statusTextView;
private final TextView totalTimeTextView; private final TextView totalTimeTextView;
@@ -66,25 +63,24 @@ public class TrackController {
private final Runnable updateTotalTimeRunnable = new Runnable() { private final Runnable updateTotalTimeRunnable = new Runnable() {
public void run() { public void run() {
if (isResumed && isRecording && !isPaused) { if (isResumed && isRecording && !isPaused) {
totalTimeTextView.setText(StringUtils.formatElapsedTimeWithHour( totalTimeTextView.setText(StringUtils.formatElapsedTimeWithHour(System.currentTimeMillis() - totalTimeTimestamp + totalTime));
System.currentTimeMillis() - totalTimeTimestamp + totalTime)); handlerUpdateTotalTime.postDelayed(this, UnitConversions.ONE_SECOND);
handler.postDelayed(this, ONE_SECOND);
} }
} }
}; };
public TrackController(Activity activity, public TrackController(Activity activity, TrackRecordingServiceConnection trackRecordingServiceConnection, boolean alwaysShow, OnClickListener recordListener, OnClickListener stopListener) {
TrackRecordingServiceConnection trackRecordingServiceConnection, boolean alwaysShow,
OnClickListener recordListener, OnClickListener stopListener) {
this.activity = activity; this.activity = activity;
this.trackRecordingServiceConnection = trackRecordingServiceConnection; this.trackRecordingServiceConnection = trackRecordingServiceConnection;
this.alwaysShow = alwaysShow; this.alwaysShow = alwaysShow;
handler = new Handler(); handlerUpdateTotalTime = new Handler();
containerView = activity.findViewById(R.id.track_controller_container); containerView = activity.findViewById(R.id.track_controller_container);
statusTextView = activity.findViewById(R.id.track_controller_status); statusTextView = activity.findViewById(R.id.track_controller_status);
totalTimeTextView = activity.findViewById(R.id.track_controller_total_time); totalTimeTextView = activity.findViewById(R.id.track_controller_total_time);
recordImageButton = activity.findViewById(R.id.track_controller_record); recordImageButton = activity.findViewById(R.id.track_controller_record);
recordImageButton.setOnClickListener(recordListener); recordImageButton.setOnClickListener(recordListener);
stopImageButton = activity.findViewById(R.id.track_controller_stop); stopImageButton = activity.findViewById(R.id.track_controller_stop);
stopImageButton.setOnClickListener(stopListener); stopImageButton.setOnClickListener(stopListener);
} }
@@ -99,34 +95,30 @@ public class TrackController {
containerView.setVisibility(visible ? View.VISIBLE : View.GONE); containerView.setVisibility(visible ? View.VISIBLE : View.GONE);
if (!visible) { if (!visible) {
handler.removeCallbacks(updateTotalTimeRunnable); handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
return; return;
} }
recordImageButton.setImageResource( recordImageButton.setImageResource(isRecording && !isPaused ? R.drawable.button_pause : R.drawable.button_record);
isRecording && !isPaused ? R.drawable.button_pause : R.drawable.button_record); recordImageButton.setContentDescription(activity.getString(isRecording && !isPaused ? R.string.image_pause : R.string.image_record));
recordImageButton.setContentDescription(activity.getString(
isRecording && !isPaused ? R.string.image_pause : R.string.image_record));
stopImageButton.setImageResource( stopImageButton.setImageResource(isRecording ? R.drawable.button_stop : R.drawable.ic_button_stop_disabled);
isRecording ? R.drawable.button_stop : R.drawable.ic_button_stop_disabled);
stopImageButton.setEnabled(isRecording); stopImageButton.setEnabled(isRecording);
statusTextView.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE); statusTextView.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
if (isRecording) { if (isRecording) {
statusTextView.setTextColor(activity.getResources() statusTextView.setTextColor(activity.getResources().getColor(isPaused ? android.R.color.white : R.color.recording_text));
.getColor(isPaused ? android.R.color.white : R.color.recording_text));
statusTextView.setText(isPaused ? R.string.generic_paused : R.string.generic_recording); statusTextView.setText(isPaused ? R.string.generic_paused : R.string.generic_recording);
} }
handler.removeCallbacks(updateTotalTimeRunnable); handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
totalTimeTextView.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE); totalTimeTextView.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
if (isRecording) { if (isRecording) {
totalTime = getTotalTime(); totalTime = getTotalTime();
totalTimeTextView.setText(StringUtils.formatElapsedTimeWithHour(totalTime)); totalTimeTextView.setText(StringUtils.formatElapsedTimeWithHour(totalTime));
if (!isPaused) { if (!isPaused) {
totalTimeTimestamp = System.currentTimeMillis(); totalTimeTimestamp = System.currentTimeMillis();
handler.postDelayed(updateTotalTimeRunnable, ONE_SECOND); handlerUpdateTotalTime.postDelayed(updateTotalTimeRunnable, UnitConversions.ONE_SECOND);
} }
} }
} }
@@ -138,7 +130,7 @@ public class TrackController {
public void onPause() { public void onPause() {
isResumed = false; isResumed = false;
handler.removeCallbacks(updateTotalTimeRunnable); handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
} }
public void hide() { public void hide() {
@@ -153,8 +145,7 @@ public class TrackController {
* Gets the total time for the current recording track. * Gets the total time for the current recording track.
*/ */
private long getTotalTime() { private long getTotalTime() {
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
.getServiceIfBound();
try { try {
return trackRecordingService != null ? trackRecordingService.getTotalTime() : 0L; return trackRecordingService != null ? trackRecordingService.getTotalTime() : 0L;
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -129,12 +129,9 @@ public class TrackDetailActivity extends AbstractTrackActivity
trackController.update(trackId == recordingTrackId, recordingTrackPaused); trackController.update(trackId == recordingTrackId, recordingTrackPaused);
if (hasPhoto && photoUri != null) { if (hasPhoto && photoUri != null) {
hasPhoto = false; hasPhoto = false;
WaypointCreationRequest waypointCreationRequest = new WaypointCreationRequest( WaypointCreationRequest waypointCreationRequest = new WaypointCreationRequest(WaypointType.WAYPOINT, false, null, null, null, null, photoUri.toString());
WaypointType.WAYPOINT, false, null, null, null, null, photoUri.toString()); long markerId = TrackRecordingServiceConnectionUtils.addMarker(TrackDetailActivity.this, trackRecordingServiceConnection, waypointCreationRequest);
long id = TrackRecordingServiceConnectionUtils.addMarker( if (markerId != -1L) {
TrackDetailActivity.this, trackRecordingServiceConnection, waypointCreationRequest);
if (id != -1L) {
FileUtils.updateMediaScanner(TrackDetailActivity.this, photoUri); FileUtils.updateMediaScanner(TrackDetailActivity.this, photoUri);
} }
} }
@@ -151,28 +148,24 @@ public class TrackDetailActivity extends AbstractTrackActivity
sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
// Note that key can be null if (key == null || key.equals(PreferencesUtils.getKey(TrackDetailActivity.this, R.string.recording_track_id_key))) {
if (key == null || key.equals( recordingTrackId = PreferencesUtils.getLong(TrackDetailActivity.this, R.string.recording_track_id_key);
PreferencesUtils.getKey(TrackDetailActivity.this, R.string.recording_track_id_key))) {
recordingTrackId = PreferencesUtils.getLong(
TrackDetailActivity.this, R.string.recording_track_id_key);
} }
if (key == null || key.equals(PreferencesUtils.getKey(
TrackDetailActivity.this, R.string.recording_track_paused_key))) { if (key == null || key.equals(PreferencesUtils.getKey(TrackDetailActivity.this, R.string.recording_track_paused_key))) {
recordingTrackPaused = PreferencesUtils.getBoolean(TrackDetailActivity.this, recordingTrackPaused = PreferencesUtils.getBoolean(TrackDetailActivity.this, R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
R.string.recording_track_paused_key,
PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
}
if (key != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
TrackDetailActivity.this.invalidateOptionsMenu();
boolean isRecording = trackId == recordingTrackId;
trackController.update(isRecording, recordingTrackPaused);
}
});
} }
if (key == null) return;
runOnUiThread(new Runnable() {
@Override
public void run() {
TrackDetailActivity.this.invalidateOptionsMenu();
boolean isRecording = trackId == recordingTrackId;
trackController.update(isRecording, recordingTrackPaused);
}
});
} }
}; };
@@ -214,8 +207,7 @@ public class TrackDetailActivity extends AbstractTrackActivity
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
trackRecordingServiceConnection = new TrackRecordingServiceConnection( trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, bindChangedCallback);
this, bindChangedCallback);
trackDataHub = TrackDataHub.newInstance(this); trackDataHub = TrackDataHub.newInstance(this);
tabHost = findViewById(android.R.id.tabhost); tabHost = findViewById(android.R.id.tabhost);
@@ -225,17 +217,12 @@ public class TrackDetailActivity extends AbstractTrackActivity
tabsAdapter = new TabsAdapter(this, tabHost, viewPager); tabsAdapter = new TabsAdapter(this, tabHost, viewPager);
TabSpec statsTabSpec = tabHost.newTabSpec(StatsFragment.STATS_FRAGMENT_TAG).setIndicator( TabSpec statsTabSpec = tabHost.newTabSpec(StatsFragment.STATS_FRAGMENT_TAG).setIndicator(getString(R.string.track_detail_stats_tab), getResources().getDrawable(R.drawable.ic_tab_stats));
getString(R.string.track_detail_stats_tab),
getResources().getDrawable(R.drawable.ic_tab_stats));
tabsAdapter.addTab(statsTabSpec, StatsFragment.class, null); tabsAdapter.addTab(statsTabSpec, StatsFragment.class, null);
TabSpec chartTabSpec = tabHost.newTabSpec(ChartFragment.CHART_FRAGMENT_TAG).setIndicator( TabSpec chartTabSpec = tabHost.newTabSpec(ChartFragment.CHART_FRAGMENT_TAG).setIndicator(getString(R.string.track_detail_chart_tab),getResources().getDrawable(R.drawable.ic_tab_chart));
getString(R.string.track_detail_chart_tab),
getResources().getDrawable(R.drawable.ic_tab_chart));
tabsAdapter.addTab(chartTabSpec, ChartFragment.class, null); tabsAdapter.addTab(chartTabSpec, ChartFragment.class, null);
if (savedInstanceState != null) { if (savedInstanceState != null) {
tabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAB_TAG_KEY)); tabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAB_TAG_KEY));
} }
@@ -245,8 +232,7 @@ public class TrackDetailActivity extends AbstractTrackActivity
tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab_indicator_mytracks); tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab_indicator_mytracks);
} }
trackController = new TrackController( trackController = new TrackController(this, trackRecordingServiceConnection, false, recordListener, stopListener);
this, trackRecordingServiceConnection, false, recordListener, stopListener);
} }
@Override @Override
@@ -323,6 +309,7 @@ public class TrackDetailActivity extends AbstractTrackActivity
@Override @Override
protected void onHomeSelected() { protected void onHomeSelected() {
/* /*
* TODO: Investigate
* According to * According to
* http://developer.android.com/training/implementing-navigation * http://developer.android.com/training/implementing-navigation
* /ancestral.html, we should use NavUtils.shouldUpRecreateTask instead of * /ancestral.html, we should use NavUtils.shouldUpRecreateTask instead of
@@ -470,14 +457,7 @@ public class TrackDetailActivity extends AbstractTrackActivity
public long getTrackId() { public long getTrackId() {
return trackId; return trackId;
} }
/**
* Gets the marker id.
*/
public long getMarkerId() {
return markerId;
}
/** /**
* Handles the data in the intent. * Handles the data in the intent.
*/ */
@@ -179,8 +179,7 @@ public class TrackDataHub implements DataSourceListener {
* @param trackDataListener the track data listener * @param trackDataListener the track data listener
* @param trackDataTypes the track data types * @param trackDataTypes the track data types
*/ */
public void registerTrackDataListener( public void registerTrackDataListener(final TrackDataListener trackDataListener, final EnumSet<TrackDataType> trackDataTypes) {
final TrackDataListener trackDataListener, final EnumSet<TrackDataType> trackDataTypes) {
runInHanderThread(new Runnable() { runInHanderThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@@ -360,8 +359,7 @@ public class TrackDataHub implements DataSourceListener {
return; return;
} }
for (TrackDataListener trackDataListener : for (TrackDataListener trackDataListener : trackDataManager.getListeners(TrackDataType.PREFERENCE)) {
trackDataManager.getListeners(TrackDataType.PREFERENCE)) {
trackDataListener.onMetricUnitsChanged(metricUnits); trackDataListener.onMetricUnitsChanged(metricUnits);
trackDataListener.onReportSpeedChanged(reportSpeed); trackDataListener.onReportSpeedChanged(reportSpeed);
trackDataListener.onRecordingGpsAccuracy(recordingGpsAccuracy); trackDataListener.onRecordingGpsAccuracy(recordingGpsAccuracy);
@@ -371,8 +369,7 @@ public class TrackDataHub implements DataSourceListener {
notifyTracksTableUpdate(trackDataManager.getListeners(TrackDataType.TRACKS_TABLE)); notifyTracksTableUpdate(trackDataManager.getListeners(TrackDataType.TRACKS_TABLE));
for (TrackDataListener listener : for (TrackDataListener listener : trackDataManager.getListeners(TrackDataType.SAMPLED_IN_TRACK_POINTS_TABLE)) {
trackDataManager.getListeners(TrackDataType.SAMPLED_IN_TRACK_POINTS_TABLE)) {
listener.clearTrackPoints(); listener.clearTrackPoints();
} }
notifyTrackPointsTableUpdate(true, notifyTrackPointsTableUpdate(true,
@@ -25,15 +25,6 @@ import android.location.Location;
*/ */
public interface TrackDataListener { public interface TrackDataListener {
/**
* Location state.
*
* @author Jimmy Shih
*/
enum LocationState {
DISABLED, NO_FIX, BAD_FIX, GOOD_FIX
}
/** /**
* Called when the track or its statistics has been updated. * Called when the track or its statistics has been updated.
* *
@@ -323,24 +323,20 @@ public class ChartFragment extends Fragment implements TrackDataListener {
needUpdate = true; needUpdate = true;
} }
boolean chartShowSpeed = PreferencesUtils.getBoolean( boolean chartShowSpeed = PreferencesUtils.getBoolean(getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT);
getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT);
if (setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed)) { if (setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed)) {
needUpdate = true; needUpdate = true;
} }
if (setSeriesEnabled(ChartView.PACE_SERIES, chartShowSpeed && !reportSpeed)) { if (setSeriesEnabled(ChartView.PACE_SERIES, chartShowSpeed && !reportSpeed)) {
needUpdate = true; needUpdate = true;
} }
if (setSeriesEnabled(ChartView.POWER_SERIES, PreferencesUtils.getBoolean( if (setSeriesEnabled(ChartView.POWER_SERIES, PreferencesUtils.getBoolean(getActivity(), R.string.chart_show_power_key, PreferencesUtils.CHART_SHOW_POWER_DEFAULT))) {
getActivity(), R.string.chart_show_power_key, PreferencesUtils.CHART_SHOW_POWER_DEFAULT))) {
needUpdate = true; needUpdate = true;
} }
if (setSeriesEnabled(ChartView.CADENCE_SERIES, PreferencesUtils.getBoolean(getActivity(), if (setSeriesEnabled(ChartView.CADENCE_SERIES, PreferencesUtils.getBoolean(getActivity(), R.string.chart_show_cadence_key, PreferencesUtils.CHART_SHOW_CADENCE_DEFAULT))) {
R.string.chart_show_cadence_key, PreferencesUtils.CHART_SHOW_CADENCE_DEFAULT))) {
needUpdate = true; needUpdate = true;
} }
if (setSeriesEnabled(ChartView.HEART_RATE_SERIES, PreferencesUtils.getBoolean(getActivity(), if (setSeriesEnabled(ChartView.HEART_RATE_SERIES, PreferencesUtils.getBoolean(getActivity(), R.string.chart_show_heart_rate_key, PreferencesUtils.CHART_SHOW_HEART_RATE_DEFAULT))) {
R.string.chart_show_heart_rate_key, PreferencesUtils.CHART_SHOW_HEART_RATE_DEFAULT))) {
needUpdate = true; needUpdate = true;
} }
if (needUpdate) { if (needUpdate) {
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.fragments;
import android.location.Location; 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.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
@@ -30,6 +31,8 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.google.android.apps.mytracks.TrackDetailActivity; import com.google.android.apps.mytracks.TrackDetailActivity;
import com.google.android.apps.mytracks.content.MyTracksLocation;
import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub; import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataListener; import com.google.android.apps.mytracks.content.TrackDataListener;
@@ -55,11 +58,8 @@ public class StatsFragment extends Fragment implements TrackDataListener {
public static final String STATS_FRAGMENT_TAG = "statsFragment"; public static final String STATS_FRAGMENT_TAG = "statsFragment";
// 1 second in milliseconds
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
private TrackDataHub trackDataHub; private TrackDataHub trackDataHub;
private Handler handler; private Handler handlerUpdateUI;
private Location lastLocation = null; private Location lastLocation = null;
private TripStatistics lastTripStatistics = null; private TripStatistics lastTripStatistics = null;
@@ -71,24 +71,22 @@ public class StatsFragment extends Fragment implements TrackDataListener {
public void run() { public void run() {
if (isResumed() && isSelectedTrackRecording()) { if (isResumed() && isSelectedTrackRecording()) {
if (!isSelectedTrackPaused() && lastTripStatistics != null) { if (!isSelectedTrackPaused() && lastTripStatistics != null) {
StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - lastTripStatistics.getStopTime() + lastTripStatistics.getTotalTime());
- lastTripStatistics.getStopTime() + lastTripStatistics.getTotalTime());
} }
handler.postDelayed(this, ONE_SECOND); handlerUpdateUI.postDelayed(this, UnitConversions.ONE_SECOND);
} }
} }
}; };
@Override @Override
public View onCreateView( public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.stats, container, false); return inflater.inflate(R.layout.stats, container, false);
} }
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
handler = new Handler(); handlerUpdateUI = new Handler();
Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon); Spinner activityTypeIcon = getView().findViewById(R.id.stats_activity_type_icon);
activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), "")); activityTypeIcon.setAdapter(TrackIconUtils.getIconSpinnerAdapter(getActivity(), ""));
@@ -118,7 +116,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
resumeTrackDataHub(); resumeTrackDataHub();
updateUi(getActivity()); updateUi(getActivity());
if (isSelectedTrackRecording()) { if (isSelectedTrackRecording()) {
handler.post(updateTotalTime); handlerUpdateUI.post(updateTotalTime);
} }
} }
@@ -126,7 +124,7 @@ public class StatsFragment extends Fragment implements TrackDataListener {
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
pauseTrackDataHub(); pauseTrackDataHub();
handler.removeCallbacks(updateTotalTime); handlerUpdateUI.removeCallbacks(updateTotalTime);
} }
@Override @Override
@@ -178,15 +176,13 @@ public class StatsFragment extends Fragment implements TrackDataListener {
if (lastLocation != null) { if (lastLocation != null) {
boolean hasFix = !LocationUtils.isLocationOld(lastLocation); boolean hasFix = !LocationUtils.isLocationOld(lastLocation);
boolean hasGoodFix = lastLocation.hasAccuracy() boolean hasGoodFix = lastLocation.hasAccuracy() && lastLocation.getAccuracy() < recordingGpsAccuracy;
&& lastLocation.getAccuracy() < recordingGpsAccuracy;
if (!hasFix || !hasGoodFix) { if (!hasFix || !hasGoodFix) {
lastLocation = null; lastLocation = null;
} }
} }
StatsUtils.setLocationValues( StatsUtils.setLocationValues(getActivity(), getActivity(), null, lastLocation, isSelectedTrackRecording());
getActivity(), getActivity(), null, lastLocation, isSelectedTrackRecording());
} }
} }
}); });
@@ -101,10 +101,7 @@ public class TrackRecordingService extends Service {
public static final double MAX_NO_MOVEMENT_SPEED = 0.224; public static final double MAX_NO_MOVEMENT_SPEED = 0.224;
private static final String TAG = TrackRecordingService.class.getSimpleName(); private static final String TAG = TrackRecordingService.class.getSimpleName();
// 1 second in milliseconds
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
// 1 minute in milliseconds // 1 minute in milliseconds
private static final long ONE_MINUTE = (long) (UnitConversions.MIN_TO_S private static final long ONE_MINUTE = (long) (UnitConversions.MIN_TO_S
* UnitConversions.S_TO_MS); * UnitConversions.S_TO_MS);
@@ -184,23 +181,18 @@ public class TrackRecordingService extends Service {
} }
if (key == null || key.equals( if (key == null || key.equals(
PreferencesUtils.getKey(context, R.string.min_recording_interval_key))) { PreferencesUtils.getKey(context, R.string.min_recording_interval_key))) {
int minRecordingInterval = PreferencesUtils.getInt(context, int minRecordingInterval = PreferencesUtils.getInt(context, R.string.min_recording_interval_key, PreferencesUtils.MIN_RECORDING_INTERVAL_DEFAULT);
R.string.min_recording_interval_key,
PreferencesUtils.MIN_RECORDING_INTERVAL_DEFAULT);
switch (minRecordingInterval) { switch (minRecordingInterval) {
case PreferencesUtils.MIN_RECORDING_INTERVAL_ADAPT_BATTERY_LIFE: case PreferencesUtils.MIN_RECORDING_INTERVAL_ADAPT_BATTERY_LIFE:
// Choose battery life over moving time accuracy. // Choose battery life over moving time accuracy.
locationListenerPolicy = new AdaptiveLocationListenerPolicy( locationListenerPolicy = new AdaptiveLocationListenerPolicy(30 * UnitConversions.ONE_SECOND, 5 * ONE_MINUTE, 5);
30 * ONE_SECOND, 5 * ONE_MINUTE, 5);
break; break;
case PreferencesUtils.MIN_RECORDING_INTERVAL_ADAPT_ACCURACY: case PreferencesUtils.MIN_RECORDING_INTERVAL_ADAPT_ACCURACY:
// Get all the updates. // Get all the updates.
locationListenerPolicy = new AdaptiveLocationListenerPolicy( locationListenerPolicy = new AdaptiveLocationListenerPolicy(UnitConversions.ONE_SECOND, 30 * UnitConversions.ONE_SECOND, 0);
ONE_SECOND, 30 * ONE_SECOND, 0);
break; break;
default: default:
locationListenerPolicy = new AbsoluteLocationListenerPolicy( locationListenerPolicy = new AbsoluteLocationListenerPolicy(minRecordingInterval * UnitConversions.ONE_SECOND);
minRecordingInterval * ONE_SECOND);
} }
} }
if (key == null || key.equals( if (key == null || key.equals(
@@ -44,7 +44,6 @@ import java.util.ArrayList;
*/ */
public class BluetoothSensorManager extends SensorManager { public class BluetoothSensorManager extends SensorManager {
private static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
private static final BluetoothAdapter bluetoothAdapter = getDefaultBluetoothAdapter(); private static final BluetoothAdapter bluetoothAdapter = getDefaultBluetoothAdapter();
private static final String TAG = BluetoothConnectionManager.class.getSimpleName(); private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
@@ -72,7 +71,7 @@ public class BluetoothSensorManager extends SensorManager {
while (adapters.isEmpty()) { while (adapters.isEmpty()) {
synchronized (mutex) { synchronized (mutex) {
try { try {
mutex.wait(ONE_SECOND); mutex.wait(UnitConversions.ONE_SECOND);
} catch (InterruptedException e) { } catch (InterruptedException e) {
Log.e(TAG, "Interrupted while waiting for default bluetooth adapter", e); Log.e(TAG, "Interrupted while waiting for default bluetooth adapter", e);
} }
@@ -30,7 +30,7 @@ import java.util.Locale;
/** /**
* Utilities for updating the statistics UI labels and values. * Utilities for updating the statistics UI labels and values.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public class StatsUtils { public class StatsUtils {
@@ -42,7 +42,7 @@ public class StatsUtils {
/** /**
* Sets the location values. * Sets the location values.
* *
* @param context the context * @param context the context
* @param activity the activity for finding views. If null, the view cannot be * @param activity the activity for finding views. If null, the view cannot be
* null * null
@@ -104,7 +104,7 @@ public class StatsUtils {
/** /**
* Sets the total time value. * Sets the total time value.
* *
* @param activity the activity * @param activity the activity
* @param totalTime the total time * @param totalTime the total time
*/ */
@@ -115,7 +115,7 @@ public class StatsUtils {
/** /**
* Sets the trip statistics values. * Sets the trip statistics values.
* *
* @param context the context * @param context the context
* @param activity the activity for finding views. If null, then view cannot * @param activity the activity for finding views. If null, then view cannot
* be null * be null
@@ -125,8 +125,7 @@ public class StatsUtils {
* @param trackIconValue the track icon value or null to hide the track icon * @param trackIconValue the track icon value or null to hide the track icon
* spinner * spinner
*/ */
public static void setTripStatisticsValues(Context context, Activity activity, View view, public static void setTripStatisticsValues(Context context, Activity activity, View view, TripStatistics tripStatistics, String trackIconValue) {
TripStatistics tripStatistics, String trackIconValue) {
boolean metricUnits = PreferencesUtils.isMetricUnits(context); boolean metricUnits = PreferencesUtils.isMetricUnits(context);
boolean reportSpeed = PreferencesUtils.isReportSpeed(context); boolean reportSpeed = PreferencesUtils.isReportSpeed(context);
@@ -158,52 +157,42 @@ public class StatsUtils {
// Set max speed/pace // Set max speed/pace
double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed(); double maxSpeed = tripStatistics == null ? Double.NaN : tripStatistics.getMaxSpeed();
setSpeed(context, getView(activity, view, R.id.stats_max_speed), R.string.stats_max_speed, setSpeed(context, getView(activity, view, R.id.stats_max_speed), R.string.stats_max_speed, R.string.stats_fastest_pace, maxSpeed, metricUnits, reportSpeed);
R.string.stats_fastest_pace, maxSpeed, metricUnits, reportSpeed);
// Set average moving speed/pace // Set average moving speed/pace
double averageMovingSpeed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed() double averageMovingSpeed = tripStatistics != null ? tripStatistics.getAverageMovingSpeed() : Double.NaN;
: Double.NaN;
setSpeed(context, getView(activity, view, R.id.stats_average_moving_speed), setSpeed(context, getView(activity, view, R.id.stats_average_moving_speed),
R.string.stats_average_moving_speed, R.string.stats_average_moving_pace, averageMovingSpeed, R.string.stats_average_moving_speed, R.string.stats_average_moving_pace, averageMovingSpeed,
metricUnits, reportSpeed); metricUnits, reportSpeed);
// Set grade/elevation // Set grade/elevation
boolean showGradeElevation = PreferencesUtils.getBoolean(context, boolean showGradeElevation = PreferencesUtils.getBoolean(context,R.string.stats_show_grade_elevation_key, PreferencesUtils.STATS_SHOW_GRADE_ELEVATION_DEFAULT);
R.string.stats_show_grade_elevation_key,
PreferencesUtils.STATS_SHOW_GRADE_ELEVATION_DEFAULT);
View gradeElevationSeparator = getView(activity, view, R.id.stats_grade_elevation_separator); View gradeElevationSeparator = getView(activity, view, R.id.stats_grade_elevation_separator);
View gradeElevationContainer = getView(activity, view, R.id.stats_grade_elevation_container);
gradeElevationSeparator.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE); gradeElevationSeparator.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
View gradeElevationContainer = getView(activity, view, R.id.stats_grade_elevation_container);
gradeElevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE); gradeElevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE);
if (showGradeElevation) { if (showGradeElevation) {
// Set grade // Set grade
double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade(); double minGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMinGrade();
double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade(); double maxGrade = tripStatistics == null ? Double.NaN : tripStatistics.getMaxGrade();
setGradeValue( setGradeValue(context, getView(activity, view, R.id.stats_grade_min), R.string.stats_min, minGrade);
context, getView(activity, view, R.id.stats_grade_min), R.string.stats_min, minGrade); setGradeValue(context, getView(activity, view, R.id.stats_grade_max), R.string.stats_max, maxGrade);
setGradeValue(
context, getView(activity, view, R.id.stats_grade_max), R.string.stats_max, maxGrade);
// Set elevation // Set elevation
double elevationGain = tripStatistics == null ? Double.NaN double elevationGain = tripStatistics == null ? Double.NaN : tripStatistics.getTotalElevationGain();
: tripStatistics.getTotalElevationGain();
double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation(); double minElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMinElevation();
double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation(); double maxElevation = tripStatistics == null ? Double.NaN : tripStatistics.getMaxElevation();
setElevationValue(context, getView(activity, view, R.id.stats_elevation_gain), setElevationValue(context, getView(activity, view, R.id.stats_elevation_gain), R.string.stats_gain, elevationGain, metricUnits);
R.string.stats_gain, elevationGain, metricUnits); setElevationValue(context, getView(activity, view, R.id.stats_elevation_min), R.string.stats_min, minElevation, metricUnits);
setElevationValue(context, getView(activity, view, R.id.stats_elevation_min), setElevationValue(context, getView(activity, view, R.id.stats_elevation_max), R.string.stats_max, maxElevation, metricUnits);
R.string.stats_min, minElevation, metricUnits);
setElevationValue(context, getView(activity, view, R.id.stats_elevation_max),
R.string.stats_max, maxElevation, metricUnits);
} }
} }
/** /**
* Sets speed. * Sets speed.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param speedLabelId the speed label id * @param speedLabelId the speed label id
@@ -212,29 +201,27 @@ public class StatsUtils {
* @param metricUnits true if metric units * @param metricUnits true if metric units
* @param reportSpeed true if report speed * @param reportSpeed true if report speed
*/ */
private static void setSpeed(Context context, View view, int speedLabelId, int paceLabelId, private static void setSpeed(Context context, View view, int speedLabelId, int paceLabelId, double speed, boolean metricUnits, boolean reportSpeed) {
double speed, boolean metricUnits, boolean reportSpeed) { String[] parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
String[] parts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
setItem(context, view, reportSpeed ? speedLabelId : paceLabelId, parts[0], parts[1]); setItem(context, view, reportSpeed ? speedLabelId : paceLabelId, parts[0], parts[1]);
} }
/** /**
* Sets distance value. * Sets distance value.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param distance the distance in meters * @param distance the distance in meters
* @param metricUnits true if metric units * @param metricUnits true if metric units
*/ */
private static void setDistanceValue( private static void setDistanceValue(Context context, View view, double distance, boolean metricUnits) {
Context context, View view, double distance, boolean metricUnits) { String[] parts = StringUtils.getDistanceParts(context, distance, metricUnits);
String[] parts = StringUtils.getDistanceParts(context, distance, metricUnits);
setItem(context, view, R.string.stats_distance, parts[0], parts[1]); setItem(context, view, R.string.stats_distance, parts[0], parts[1]);
} }
/** /**
* Sets a time value. * Sets a time value.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param labelId the label id * @param labelId the label id
@@ -247,15 +234,14 @@ public class StatsUtils {
/** /**
* Sets an elevation value. * Sets an elevation value.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param labelId the label id * @param labelId the label id
* @param elevation the elevation in meters * @param elevation the elevation in meters
* @param metricUnits true if metric units * @param metricUnits true if metric units
*/ */
private static void setElevationValue( private static void setElevationValue(Context context, View view, int labelId, double elevation, boolean metricUnits) {
Context context, View view, int labelId, double elevation, boolean metricUnits) {
String value; String value;
String unit; String unit;
if (Double.isNaN(elevation) || Double.isInfinite(elevation)) { if (Double.isNaN(elevation) || Double.isInfinite(elevation)) {
@@ -276,7 +262,7 @@ public class StatsUtils {
/** /**
* Sets a grade value. * Sets a grade value.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param labelId the label id * @param labelId the label id
@@ -290,14 +276,13 @@ public class StatsUtils {
/** /**
* Sets a coordinate value. * Sets a coordinate value.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param labelId the label id * @param labelId the label id
* @param coordinate the coordinate in degrees * @param coordinate the coordinate in degrees
*/ */
private static void setCoordinateValue( private static void setCoordinateValue(Context context, View view, int labelId, double coordinate) {
Context context, View view, int labelId, double coordinate) {
String value = Double.isNaN(coordinate) || Double.isInfinite(coordinate) ? null String value = Double.isNaN(coordinate) || Double.isInfinite(coordinate) ? null
: StringUtils.formatCoordinate(coordinate); : StringUtils.formatCoordinate(coordinate);
setItem(context, view, labelId, value, null); setItem(context, view, labelId, value, null);
@@ -305,7 +290,7 @@ public class StatsUtils {
/** /**
* Sets an item. * Sets an item.
* *
* @param context the context * @param context the context
* @param view the containing view * @param view the containing view
* @param labelId the label id. -1 to hide the label * @param labelId the label id. -1 to hide the label
@@ -345,7 +330,7 @@ public class StatsUtils {
/** /**
* Get a view. * Get a view.
* *
* @param activity the activity * @param activity the activity
* @param view the containing view * @param view the containing view
* @param id the id * @param id the id
@@ -25,6 +25,8 @@ public class UnitConversions {
private UnitConversions() {} private UnitConversions() {}
// Time // Time
// 1 second in milliseconds
public static final long ONE_SECOND = (long) UnitConversions.S_TO_MS;
// multiplication factor to convert seconds to milliseconds // multiplication factor to convert seconds to milliseconds
public static final double S_TO_MS = 1000.0; public static final double S_TO_MS = 1000.0;
@@ -1056,8 +1056,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
if (location instanceof MyTracksLocation && !cursor.isNull(indexes.sensorIndex)) { if (location instanceof MyTracksLocation && !cursor.isNull(indexes.sensorIndex)) {
MyTracksLocation myTracksLocation = (MyTracksLocation) location; MyTracksLocation myTracksLocation = (MyTracksLocation) location;
try { try {
myTracksLocation.setSensorDataSet( myTracksLocation.setSensorDataSet(SensorDataSet.parseFrom(cursor.getBlob(indexes.sensorIndex)));
SensorDataSet.parseFrom(cursor.getBlob(indexes.sensorIndex)));
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
Log.w(TAG, "Failed to parse sensor data.", e); Log.w(TAG, "Failed to parse sensor data.", e);
} }
@@ -79,11 +79,9 @@ public class TripStatistics implements Parcelable {
totalTime = other.totalTime; totalTime = other.totalTime;
movingTime = other.movingTime; movingTime = other.movingTime;
latitudeExtremities.set(other.latitudeExtremities.getMin(), other.latitudeExtremities.getMax()); latitudeExtremities.set(other.latitudeExtremities.getMin(), other.latitudeExtremities.getMax());
longitudeExtremities.set( longitudeExtremities.set(other.longitudeExtremities.getMin(), other.longitudeExtremities.getMax());
other.longitudeExtremities.getMin(), other.longitudeExtremities.getMax());
maxSpeed = other.maxSpeed; maxSpeed = other.maxSpeed;
elevationExtremities.set( elevationExtremities.set(other.elevationExtremities.getMin(), other.elevationExtremities.getMax());
other.elevationExtremities.getMin(), other.elevationExtremities.getMax());
totalElevationGain = other.totalElevationGain; totalElevationGain = other.totalElevationGain;
gradeExtremities.set(other.gradeExtremities.getMin(), other.gradeExtremities.getMax()); gradeExtremities.set(other.gradeExtremities.getMin(), other.gradeExtremities.getMax());
} }