forked from upstream-mirrors/OpenTracks
Intervals: TrackDataHub instead of ContentProvider. Fixes #453.
This commit is contained in:
@@ -253,7 +253,7 @@ public class TrackRecordedActivity extends AbstractListActivity implements Choos
|
|||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordedFragment.newInstance(trackId);
|
return StatisticsRecordedFragment.newInstance(trackId);
|
||||||
case 1:
|
case 1:
|
||||||
return IntervalsFragment.newInstance(trackId);
|
return IntervalsFragment.newInstance();
|
||||||
case 2:
|
case 2:
|
||||||
return ChartFragment.newInstance(false);
|
return ChartFragment.newInstance(false);
|
||||||
case 3:
|
case 3:
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
// Preferences
|
// Preferences
|
||||||
private boolean recordingTrackPaused;
|
private boolean recordingTrackPaused;
|
||||||
|
|
||||||
// Intervals recording fragment needs Track.Id when the activity creates it and knowing when category change.
|
|
||||||
private OnTrackRecordingListener intervalsListener;
|
|
||||||
|
|
||||||
private final Runnable bindChangedCallback = new Runnable() {
|
private final Runnable bindChangedCallback = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -85,9 +82,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
if (trackId == null) {
|
if (trackId == null) {
|
||||||
// trackId isn't initialized -> leads a new recording.
|
// trackId isn't initialized -> leads a new recording.
|
||||||
trackId = service.startNewTrack();
|
trackId = service.startNewTrack();
|
||||||
if (intervalsListener != null) {
|
|
||||||
intervalsListener.onTrackId(trackId);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// trackId is initialized -> resumes the track.
|
// trackId is initialized -> resumes the track.
|
||||||
service.resumeTrack(trackId);
|
service.resumeTrack(trackId);
|
||||||
@@ -370,7 +364,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
Track track = contentProviderUtils.getTrack(trackId);
|
Track track = contentProviderUtils.getTrack(trackId);
|
||||||
String category = getString(TrackIconUtils.getIconActivityType(iconValue));
|
String category = getString(TrackIconUtils.getIconActivityType(iconValue));
|
||||||
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
TrackUtils.updateTrack(this, track, null, category, null, contentProviderUtils);
|
||||||
intervalsListener.onCategoryChanged(category);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
private class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||||
@@ -391,7 +384,7 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
case 0:
|
case 0:
|
||||||
return StatisticsRecordingFragment.newInstance();
|
return StatisticsRecordingFragment.newInstance();
|
||||||
case 1:
|
case 1:
|
||||||
return IntervalsFragment.IntervalsRecordingFragment.newInstance(trackId);
|
return IntervalsFragment.IntervalsRecordingFragment.newInstance();
|
||||||
case 2:
|
case 2:
|
||||||
return ChartFragment.newInstance(false);
|
return ChartFragment.newInstance(false);
|
||||||
case 3:
|
case 3:
|
||||||
@@ -417,16 +410,4 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public interface OnTrackRecordingListener {
|
|
||||||
void onTrackId(Track.Id trackId);
|
|
||||||
void onCategoryChanged(String category);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTrackIdListener(OnTrackRecordingListener listener) {
|
|
||||||
this.intervalsListener = listener;
|
|
||||||
if (trackId != null) {
|
|
||||||
listener.onTrackId(trackId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -54,17 +54,15 @@ import de.dennisguse.opentracks.util.PreferencesUtils;
|
|||||||
public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target number of track points displayed by the map overlay.
|
* Target number of track points displayed by the diagrams (recommended).
|
||||||
* We may display more than this number of points.
|
* We may display more than this number of points.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
private static final int TARGET_DISPLAYED_TRACKPOINTS = 5000;
|
private static final int TARGET_DISPLAYED_TRACKPOINTS = 5000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of markers to displayed.
|
* Maximum number of markers to displayed in the diagrams.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Deprecated
|
|
||||||
private static final int MAX_DISPLAYED_MARKERS = 128;
|
private static final int MAX_DISPLAYED_MARKERS = 128;
|
||||||
|
|
||||||
private static final String TAG = TrackDataHub.class.getSimpleName();
|
private static final String TAG = TrackDataHub.class.getSimpleName();
|
||||||
|
|||||||
@@ -15,14 +15,16 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.TrackRecordingActivity;
|
import de.dennisguse.opentracks.TrackActivityDataHubInterface;
|
||||||
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
|
import de.dennisguse.opentracks.adapters.IntervalStatisticsAdapter;
|
||||||
|
import de.dennisguse.opentracks.content.TrackDataHub;
|
||||||
|
import de.dennisguse.opentracks.content.TrackDataListener;
|
||||||
|
import de.dennisguse.opentracks.content.data.Marker;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
import de.dennisguse.opentracks.viewmodels.IntervalStatistics;
|
||||||
@@ -31,12 +33,10 @@ import de.dennisguse.opentracks.viewmodels.IntervalStatisticsModel;
|
|||||||
/**
|
/**
|
||||||
* A fragment to display the intervals from recorded track.
|
* A fragment to display the intervals from recorded track.
|
||||||
*/
|
*/
|
||||||
public class IntervalsFragment extends Fragment {
|
public class IntervalsFragment extends Fragment implements TrackDataListener {
|
||||||
|
|
||||||
private static final String TAG = IntervalsFragment.class.getSimpleName();
|
private static final String TAG = IntervalsFragment.class.getSimpleName();
|
||||||
|
|
||||||
private static final String TRACK_ID_KEY = "trackId";
|
|
||||||
|
|
||||||
private IntervalStatisticsModel viewModel;
|
private IntervalStatisticsModel viewModel;
|
||||||
private ListView intervalListView;
|
private ListView intervalListView;
|
||||||
protected IntervalStatisticsAdapter.StackMode stackModeListView;
|
protected IntervalStatisticsAdapter.StackMode stackModeListView;
|
||||||
@@ -49,7 +49,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
|
|
||||||
private TextView rateLabel;
|
private TextView rateLabel;
|
||||||
|
|
||||||
private Track.Id trackId;
|
private TrackDataHub trackDataHub;
|
||||||
private String category;
|
private String category;
|
||||||
|
|
||||||
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
protected final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (preferences, key) -> {
|
||||||
@@ -58,19 +58,12 @@ public class IntervalsFragment extends Fragment {
|
|||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
spinnerAdapter.notifyDataSetChanged();
|
spinnerAdapter.notifyDataSetChanged();
|
||||||
setRateLabel();
|
|
||||||
intervalChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Fragment newInstance(Track.Id trackId) {
|
public static Fragment newInstance() {
|
||||||
Bundle bundle = new Bundle();
|
return new IntervalsFragment();
|
||||||
bundle.putParcelable(TRACK_ID_KEY, trackId);
|
|
||||||
|
|
||||||
Fragment fragment = new IntervalsFragment();
|
|
||||||
fragment.setArguments(bundle);
|
|
||||||
return fragment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,12 +78,6 @@ public class IntervalsFragment extends Fragment {
|
|||||||
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
PreferencesUtils.register(getContext(), sharedPreferenceChangeListener);
|
||||||
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
intervalUnit = PreferencesUtils.isMetricUnits(getContext()) ? getContext().getString(R.string.unit_kilometer) : getContext().getString(R.string.unit_mile);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
|
||||||
setTrackId(savedInstanceState.getParcelable(TRACK_ID_KEY));
|
|
||||||
} else {
|
|
||||||
setTrackId(getArguments().getParcelable(TRACK_ID_KEY));
|
|
||||||
}
|
|
||||||
|
|
||||||
rateLabel = view.findViewById(R.id.interval_rate);
|
rateLabel = view.findViewById(R.id.interval_rate);
|
||||||
|
|
||||||
intervalListView = view.findViewById(R.id.interval_list);
|
intervalListView = view.findViewById(R.id.interval_list);
|
||||||
@@ -98,7 +85,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
|
|
||||||
stackModeListView = IntervalStatisticsAdapter.StackMode.STACK_FROM_TOP;
|
stackModeListView = IntervalStatisticsAdapter.StackMode.STACK_FROM_TOP;
|
||||||
|
|
||||||
viewModel = new ViewModelProvider(this).get(IntervalStatisticsModel.class);
|
viewModel = new IntervalStatisticsModel();
|
||||||
|
|
||||||
spinnerIntervals = view.findViewById(R.id.spinner_intervals);
|
spinnerIntervals = view.findViewById(R.id.spinner_intervals);
|
||||||
|
|
||||||
@@ -124,7 +111,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
selectedInterval = IntervalStatisticsModel.IntervalOption.values()[i];
|
selectedInterval = IntervalStatisticsModel.IntervalOption.values()[i];
|
||||||
intervalChanged();
|
loadIntervals();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,9 +119,18 @@ public class IntervalsFragment extends Fragment {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setRateLabel();
|
@Override
|
||||||
intervalChanged();
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
resumeTrackDataHub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
pauseTrackDataHub();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -149,60 +145,108 @@ public class IntervalsFragment extends Fragment {
|
|||||||
viewModel = null;
|
viewModel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putParcelable(TRACK_ID_KEY, trackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
setTrackId(trackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update intervals through {@link IntervalStatisticsModel} view model.
|
* Update intervals through {@link IntervalStatisticsModel} view model.
|
||||||
*/
|
*/
|
||||||
public void intervalChanged() {
|
protected synchronized void loadIntervals() {
|
||||||
if (viewModel == null || intervalListView == null) {
|
if (viewModel == null || intervalListView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveData<IntervalStatistics> liveData = viewModel.getIntervalStats(trackId, selectedInterval);
|
boolean metricUnits = PreferencesUtils.isMetricUnits(getContext()) ? true : false;
|
||||||
liveData.observe(getActivity(), intervalStatistics -> {
|
IntervalStatistics intervalStatistics = viewModel.getIntervalStats(metricUnits, selectedInterval);
|
||||||
if (intervalStatistics != null) {
|
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), category, stackModeListView);
|
||||||
adapter = new IntervalStatisticsAdapter(getContext(), intervalStatistics.getIntervalList(), category, stackModeListView);
|
intervalListView.setAdapter(adapter);
|
||||||
intervalListView.setAdapter(adapter);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes the trackDataHub.
|
||||||
|
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
|
||||||
|
*/
|
||||||
|
private synchronized void resumeTrackDataHub() {
|
||||||
|
trackDataHub = ((TrackActivityDataHubInterface) getActivity()).getTrackDataHub();
|
||||||
|
trackDataHub.registerTrackDataListener(this, true, false, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pauses the trackDataHub.
|
||||||
|
* Needs to be synchronized because trackDataHub can be accessed by multiple threads.
|
||||||
|
*/
|
||||||
|
private synchronized void pauseTrackDataHub() {
|
||||||
|
trackDataHub.unregisterTrackDataListener(this);
|
||||||
|
trackDataHub = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrackUpdated(Track track) {
|
||||||
|
if (isResumed()) {
|
||||||
|
// Set category.
|
||||||
|
category = track != null ? track.getCategory() : "";
|
||||||
|
|
||||||
|
// Set rate label.
|
||||||
|
if (rateLabel != null) {
|
||||||
|
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext(), category);
|
||||||
|
rateLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTrackId(Track.Id trackId) {
|
|
||||||
this.trackId = trackId;
|
|
||||||
if (this.trackId != null) {
|
|
||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getContext());
|
|
||||||
Track track = contentProviderUtils.getTrack(this.trackId);
|
|
||||||
setCategory(track.getCategory());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCategory(String category) {
|
@Override
|
||||||
if (this.category == null || !this.category.equals(category)) {
|
public void clearTrackPoints() {
|
||||||
this.category = category;
|
if (isResumed()) {
|
||||||
setRateLabel();
|
viewModel.clear();
|
||||||
intervalChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRateLabel() {
|
@Override
|
||||||
if (rateLabel != null) {
|
public void onSampledInTrackPoint(TrackPoint trackPoint) {
|
||||||
boolean reportSpeed = PreferencesUtils.isReportSpeed(getContext(), category);
|
if (isResumed()) {
|
||||||
rateLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace);
|
viewModel.add(trackPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IntervalsRecordingFragment extends IntervalsFragment implements TrackRecordingActivity.OnTrackRecordingListener {
|
@Override
|
||||||
|
public void onSampledOutTrackPoint(TrackPoint trackPoint) {
|
||||||
|
if (isResumed()) {
|
||||||
|
viewModel.add(trackPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewTrackPointsDone() {
|
||||||
|
if (isResumed()) {
|
||||||
|
runOnUiThread(() -> loadIntervals());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearMarkers() {
|
||||||
|
// We don't care.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewMarker(Marker marker) {
|
||||||
|
// We don't care.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewMarkersDone() {
|
||||||
|
// We don't care.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a runnable on the UI thread.
|
||||||
|
*
|
||||||
|
* @param runnable the runnable
|
||||||
|
*/
|
||||||
|
private void runOnUiThread(Runnable runnable) {
|
||||||
|
FragmentActivity fragmentActivity = getActivity();
|
||||||
|
if (fragmentActivity != null) {
|
||||||
|
fragmentActivity.runOnUiThread(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IntervalsRecordingFragment extends IntervalsFragment {
|
||||||
// Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience.
|
// Refreshing intervals stats it's not so demanding so 5 seconds is enough to balance performance and user experience.
|
||||||
private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS;
|
private static final long UI_UPDATE_INTERVAL = 5 * UnitConversions.ONE_SECOND_MS;
|
||||||
|
|
||||||
@@ -218,19 +262,13 @@ public class IntervalsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Fragment newInstance(Track.Id trackId) {
|
public static Fragment newInstance() {
|
||||||
Bundle bundle = new Bundle();
|
return new IntervalsRecordingFragment();
|
||||||
bundle.putParcelable(TRACK_ID_KEY, trackId);
|
|
||||||
|
|
||||||
Fragment fragment = new IntervalsRecordingFragment();
|
|
||||||
fragment.setArguments(bundle);
|
|
||||||
return fragment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
((TrackRecordingActivity) getActivity()).setTrackIdListener(this);
|
|
||||||
intervalHandler = new Handler();
|
intervalHandler = new Handler();
|
||||||
stackModeListView = IntervalStatisticsAdapter.StackMode.STACK_FROM_BOTTOM;
|
stackModeListView = IntervalStatisticsAdapter.StackMode.STACK_FROM_BOTTOM;
|
||||||
}
|
}
|
||||||
@@ -248,17 +286,7 @@ public class IntervalsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateIntervals() {
|
private void updateIntervals() {
|
||||||
intervalChanged();
|
loadIntervals();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTrackId(Track.Id trackId) {
|
|
||||||
setTrackId(trackId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCategoryChanged(String category) {
|
|
||||||
setCategory(category);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,45 @@
|
|||||||
package de.dennisguse.opentracks.viewmodels;
|
package de.dennisguse.opentracks.viewmodels;
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This view model is used to load intervals for a track.
|
* This model is used to load intervals for a track.
|
||||||
* It uses a default interval but it can be set from outside to manage the interval length.
|
* It uses a default interval but it can be set from outside to manage the interval length.
|
||||||
*/
|
*/
|
||||||
public class IntervalStatisticsModel extends AndroidViewModel {
|
public class IntervalStatisticsModel {
|
||||||
|
|
||||||
private MutableLiveData<IntervalStatistics> intervalStats = new MutableLiveData<>();
|
private IntervalStatistics intervalStats;
|
||||||
|
private List<TrackPoint> trackPoints = new ArrayList<>();
|
||||||
|
|
||||||
public IntervalStatisticsModel(@NonNull Application application) {
|
public IntervalStatistics getIntervalStats(boolean metricUnits, @Nullable IntervalOption interval) {
|
||||||
super(application);
|
synchronized (trackPoints) {
|
||||||
|
if (interval == null) {
|
||||||
|
interval = IntervalOption.OPTION_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalStats = new IntervalStatistics();
|
||||||
|
float distanceInterval = metricUnits ? (float) (interval.getValue() * UnitConversions.KM_TO_M) : (float) (interval.getValue() * UnitConversions.MI_TO_M);
|
||||||
|
intervalStats.build(trackPoints, distanceInterval);
|
||||||
|
return intervalStats;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<IntervalStatistics> getIntervalStats(@Nullable Track.Id trackId, @Nullable IntervalOption interval) {
|
public void add(TrackPoint trackPoint) {
|
||||||
if (interval == null) {
|
synchronized (trackPoints) {
|
||||||
interval = IntervalOption.OPTION_1;
|
trackPoints.add(trackPoint);
|
||||||
}
|
}
|
||||||
if (trackId != null) {
|
|
||||||
loadIntervalStats(trackId, interval);
|
|
||||||
}
|
|
||||||
return intervalStats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadIntervalStats(final Track.Id trackId, IntervalOption interval) {
|
public void clear() {
|
||||||
new Thread(() -> {
|
synchronized (trackPoints) {
|
||||||
Context context = getApplication().getApplicationContext();
|
trackPoints.clear();
|
||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
}
|
||||||
List<TrackPoint> trackPointList = contentProviderUtils.getTrackPoints(trackId);
|
|
||||||
|
|
||||||
IntervalStatistics intervalStatistics = new IntervalStatistics();
|
|
||||||
float distanceInterval = PreferencesUtils.isMetricUnits(context) ? (float) (interval.getValue() * UnitConversions.KM_TO_M) : (float) (interval.getValue() * UnitConversions.MI_TO_M);
|
|
||||||
intervalStatistics.build(trackPointList, distanceInterval);
|
|
||||||
|
|
||||||
intervalStats.postValue(intervalStatistics);
|
|
||||||
}).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user