TrackRecordingService: extracted storing data into TrackRecordingManager.

Part of #822.
This commit is contained in:
Dennis Guse
2021-07-17 17:54:07 +02:00
parent a4580fc84e
commit bd5bf530f0
6 changed files with 323 additions and 263 deletions
@@ -243,9 +243,9 @@ public class ContentProviderUtils {
* @param track the track
* @return the content provider URI of the inserted track.
*/
///TODO Return Track.Id
public Uri insertTrack(Track track) {
return contentResolver.insert(TracksColumns.CONTENT_URI, createContentValues(track));
public Track.Id insertTrack(Track track) {
Uri uri = contentResolver.insert(TracksColumns.CONTENT_URI, createContentValues(track));
return new Track.Id(ContentUris.parseId(uri));
}
/**
@@ -1,6 +1,5 @@
package de.dennisguse.opentracks.io.file.importer;
import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
@@ -149,8 +148,7 @@ public class TrackImporter {
updater.addTrackPoints(trackPoints, recordingDistanceInterval);
track.setTrackStatistics(updater.getTrackStatistics());
Uri trackUri = contentProviderUtils.insertTrack(track);
Track.Id trackId = new Track.Id(ContentUris.parseId(trackUri));
Track.Id trackId = contentProviderUtils.insertTrack(track);
// Store TrackPoints
adjustTrackPoints();
@@ -0,0 +1,288 @@
package de.dennisguse.opentracks.services;
import android.content.ContentUris;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.services.handlers.HandlerServer;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.TrackIconUtils;
import de.dennisguse.opentracks.util.TrackNameUtils;
class TrackRecordingManager {
private static final String TAG = TrackRecordingManager.class.getSimpleName();
private final ContentProviderUtils contentProviderUtils;
private final Context context;
private Distance recordingDistanceInterval;
private Distance maxRecordingDistance;
private Track track;
private TrackStatisticsUpdater trackStatisticsUpdater;
private TrackPoint lastTrackPoint;
private TrackPoint lastValidTrackPoint;
private boolean isIdle;
TrackRecordingManager(Context context) {
this.context = context;
contentProviderUtils = new ContentProviderUtils(context);
}
Track.Id start(TrackPoint segmentStartTrackPoint) {
// Insert a track
track = new Track();
track.setId(contentProviderUtils.insertTrack(track));
trackStatisticsUpdater = new TrackStatisticsUpdater();
insertTrackPoint(track, segmentStartTrackPoint);
//TODO Pass TrackPoint
track.setName(TrackNameUtils.getTrackName(context, track.getId(), segmentStartTrackPoint.getTime()));
String category = PreferencesUtils.getDefaultActivity(PreferencesUtils.getSharedPreferences(context), context); //TODO Re-use sharedpreferences
track.setCategory(category);
track.setIcon(TrackIconUtils.getIconValue(context, category));
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
contentProviderUtils.updateTrack(track); //TODO Could we do this in the insert?
return track.getId();
}
//TODO Handle non-existing trackId? Start a new track or exception?
void resume(@NonNull Track.Id trackId, @NonNull TrackPoint segmentStartTrackPoint) {
track = contentProviderUtils.getTrack(trackId);
if (track == null) {
Log.e(TAG, "Ignore resumeTrack. Track " + trackId.getId() + " does not exists.");
return;
}
trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics());
insertTrackPoint(track, segmentStartTrackPoint);
}
void pause(HandlerServer handlerServer) {
if (lastTrackPoint != null) {
insertTrackPointIfNewer(track, lastTrackPoint);
}
insertTrackPoint(track, handlerServer.createSegmentEnd());
}
void end(HandlerServer handlerServer) {
if (lastTrackPoint != null) {
insertTrackPointIfNewer(track, lastTrackPoint);
}
TrackPoint segmentEnd = handlerServer.createSegmentEnd();
insertTrackPoint(track, segmentEnd);
track = null;
trackStatisticsUpdater = null;
lastTrackPoint = null;
lastValidTrackPoint = null;
isIdle = false;
}
Pair<Track, Pair<TrackPoint, SensorDataSet>> get(HandlerServer handlerServer) {
if (handlerServer == null) {
return null;
}
TrackStatisticsUpdater tmpTrackStatisticsUpdater = getTrackStatisticsUpdater();
Pair<TrackPoint, SensorDataSet> current = handlerServer.createCurrentTrackPoint(lastTrackPoint);
tmpTrackStatisticsUpdater.addTrackPoint(current.first, recordingDistanceInterval);
Track track = getTrack(); //Get copy
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
return new Pair<>(track, current);
}
public Marker.Id insertMarker(String name, String category, String description, String photoUrl) {
if (name == null) {
Integer nextMarkerNumber = contentProviderUtils.getNextMarkerNumber(track.getId());
if (nextMarkerNumber == null) {
nextMarkerNumber = 1;
}
name = context.getString(R.string.marker_name_format, nextMarkerNumber + 1);
}
TrackPoint trackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
if (trackPoint == null) {
Log.i(TAG, "Could not create a marker as trackPoint is unknown.");
return null;
}
category = category != null ? category : "";
description = description != null ? description : "";
String icon = context.getString(R.string.marker_icon_url);
photoUrl = photoUrl != null ? photoUrl : "";
// Insert marker
Marker marker = new Marker(name, description, category, icon, track.getId(), getTrackStatistics(), trackPoint, photoUrl);
Uri uri = contentProviderUtils.insertMarker(marker);
return new Marker.Id(ContentUris.parseId(uri));
}
void onNewTrackPoint(TrackPoint trackPoint, Distance thresholdHorizontalAccuracy) {
//TODO Figure out how to avoid loading the lastValidTrackPoint from the database
TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
//Storing trackPoint
// Always insert the first segment location
if (!currentSegmentHasTrackPoint()) {
insertTrackPoint(track, trackPoint);
lastTrackPoint = trackPoint;
return;
}
Distance distanceToLastTrackLocation = trackPoint.distanceToPrevious(lastValidTrackPoint);
if (distanceToLastTrackLocation.greaterThan(maxRecordingDistance)) {
insertTrackPointIfNewer(track, lastTrackPoint);
trackPoint.setType(TrackPoint.Type.SEGMENT_START_AUTOMATIC);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
if (trackPoint.hasSensorData() || distanceToLastTrackLocation.greaterOrEqualThan(recordingDistanceInterval)) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
if (!isIdle && !trackPoint.isMoving()) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = true;
lastTrackPoint = trackPoint;
return;
}
if (isIdle && trackPoint.isMoving()) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
Log.d(TAG, "Not recording TrackPoint, idle");
lastTrackPoint = trackPoint;
}
Track getTrack() {
return contentProviderUtils.getTrack(track.getId()); //Copy in memory; not via DB
}
//Functionality that uses this method should happen here.
@Deprecated
TrackStatisticsUpdater getTrackStatisticsUpdater() {
return new TrackStatisticsUpdater(trackStatisticsUpdater);
}
TrackStatistics getTrackStatistics() {
return trackStatisticsUpdater.getTrackStatistics();
}
/**
* Gets the last valid track point in the current segment.
*
* @param trackId the track id
* @return the location or null
*/
@Deprecated
//Use lastValidTrackPoint
private TrackPoint getLastValidTrackPointInCurrentSegment(Track.Id trackId) {
if (!currentSegmentHasTrackPoint()) {
return null;
}
return contentProviderUtils.getLastValidTrackPoint(trackId);
}
private boolean currentSegmentHasTrackPoint() {
return lastTrackPoint != null;
}
/**
* Inserts a trackPoint if this trackPoint is different than lastValidTrackPoint.
*
* @param track the track
* @param trackPoint the trackPoint
*/
private void insertTrackPointIfNewer(@NonNull Track track, @NonNull TrackPoint trackPoint) {
TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
if (lastValidTrackPoint != null && trackPoint.getTime().equals(lastValidTrackPoint.getTime())) {
// Do not insert if inserted already
Log.w(TAG, "Ignore insertTrackPoint. trackPoint time same as last valid track point time.");
return;
}
insertTrackPoint(track, trackPoint);
}
/**
* Inserts a trackPoint.
*
* @param track the track
* @param trackPoint the trackPoint
*/
private void insertTrackPoint(@NonNull Track track, @NonNull TrackPoint trackPoint) {
try {
contentProviderUtils.insertTrackPoint(trackPoint, track.getId());
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
contentProviderUtils.updateTrack(track);
} catch (SQLiteException e) {
/*
* Insert failed, most likely because of SqlLite error code 5 (SQLite_BUSY).
* This is expected to happen extremely rarely (if our listener gets invoked twice at about the same time).
*/
Log.w(TAG, "SQLiteException", e);
}
}
public void onSharedPreferenceChanged(@NonNull SharedPreferences sharedPreferences, String key) {
if (PreferencesUtils.isKey(context, R.string.recording_distance_interval_key, key)) {
recordingDistanceInterval = PreferencesUtils.getRecordingDistanceInterval(sharedPreferences, context);
}
if (PreferencesUtils.isKey(context, R.string.max_recording_distance_key, key)) {
maxRecordingDistance = PreferencesUtils.getMaxRecordingDistance(sharedPreferences, context);
}
}
}
@@ -18,13 +18,10 @@ package de.dennisguse.opentracks.services;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager.WakeLock;
@@ -38,7 +35,6 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.time.Duration;
import java.time.Instant;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.TrackListActivity;
@@ -47,7 +43,6 @@ import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.content.provider.CustomContentProvider;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.io.file.exporter.ExportServiceResultReceiver;
@@ -58,13 +53,10 @@ import de.dennisguse.opentracks.services.tasks.AnnouncementPeriodicTask;
import de.dennisguse.opentracks.services.tasks.PeriodicTaskExecutor;
import de.dennisguse.opentracks.settings.SettingsActivity;
import de.dennisguse.opentracks.stats.TrackStatistics;
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
import de.dennisguse.opentracks.util.ExportUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.SystemUtils;
import de.dennisguse.opentracks.util.TrackIconUtils;
import de.dennisguse.opentracks.util.TrackNameUtils;
/**
* A background service that registers a location listener and records track points.
@@ -83,10 +75,11 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
public static final GpsStatusValue STATUS_GPS_DEFAULT = GpsStatusValue.GPS_NONE;
// The following variables are set in onCreate:
private ContentProviderUtils contentProviderUtils;
private PeriodicTaskExecutor voiceExecutor;
private TrackRecordingServiceNotificationManager notificationManager;
private TrackRecordingManager trackRecordingManager;
private final EGM2008CorrectionManager egm2008CorrectionManager = new EGM2008CorrectionManager();
private Handler handler;
@@ -106,8 +99,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
private SharedPreferences sharedPreferences;
private Distance recordingDistanceInterval;
private Distance maxRecordingDistance;
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
@@ -120,27 +111,19 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
if (PreferencesUtils.isKey(context, R.string.voice_frequency_key, key)) {
voiceExecutor.setTaskFrequency(PreferencesUtils.getVoiceFrequency(sharedPreferences, context));
}
if (PreferencesUtils.isKey(context, R.string.recording_distance_interval_key, key)) {
recordingDistanceInterval = PreferencesUtils.getRecordingDistanceInterval(sharedPreferences, context);
}
if (PreferencesUtils.isKey(context, R.string.max_recording_distance_key, key)) {
maxRecordingDistance = PreferencesUtils.getMaxRecordingDistance(sharedPreferences, context);
}
handlerServer.onSharedPreferenceChanged(sharedPreferences, key);
trackRecordingManager.onSharedPreferenceChanged(sharedPreferences, key);
}
};
// The following variables are set when recording:
private WakeLock wakeLock;
private TrackStatisticsUpdater trackStatisticsUpdater;
private TrackPoint lastTrackPoint;
private boolean isIdle;
private final Binder binder = new Binder();
private HandlerServer handlerServer;
private HandlerServer handlerServer; //TODO Move to TrackRecordingManager?
private RecordingStatus recordingStatus;
private MutableLiveData<RecordingStatus> recordingStatusObservable;
@@ -158,9 +141,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
gpsStatusObservable = new MutableLiveData<>(STATUS_GPS_DEFAULT);
recordingDataObservable = new MutableLiveData<>(NOT_RECORDING);
trackRecordingManager = new TrackRecordingManager(this);
handlerServer = new HandlerServer(this);
contentProviderUtils = new ContentProviderUtils(this);
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTask.Factory());
notificationManager = new TrackRecordingServiceNotificationManager(this);
@@ -199,8 +182,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
voiceExecutor = null;
}
contentProviderUtils = null;
// This should be the next to last operation
wakeLock = SystemUtils.releaseWakeLock(wakeLock);
@@ -219,16 +200,18 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return recordingStatus.isPaused();
}
@Deprecated //TODO Only used by announcements; pass data instead of reference
public Track.Id getRecordingTrackId() {
return recordingStatus.getTrackId();
}
//TODO
@Deprecated //TODO Only used by announcements; pass data instead of reference
public TrackStatistics getTrackStatistics() {
if (trackStatisticsUpdater == null) {
if (!isRecording()) {
return null;
}
return trackStatisticsUpdater.getTrackStatistics();
return trackRecordingManager.getTrackStatistics();
}
public Marker.Id insertMarker(String name, String category, String description, String photoUrl) {
@@ -236,31 +219,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return null;
}
if (name == null) {
Integer nextMarkerNumber = contentProviderUtils.getNextMarkerNumber(getRecordingTrackId());
if (nextMarkerNumber == null) {
nextMarkerNumber = 1;
}
name = getString(R.string.marker_name_format, nextMarkerNumber + 1);
}
TrackPoint trackPoint = getLastValidTrackPointInCurrentSegment(getRecordingTrackId());
if (trackPoint == null) {
Log.i(TAG, "Could not create a marker as trackPoint is unknown.");
return null;
}
category = category != null ? category : "";
description = description != null ? description : "";
String icon = getString(R.string.marker_icon_url);
photoUrl = photoUrl != null ? photoUrl : "";
TrackStatistics stats = trackStatisticsUpdater.getTrackStatistics();
// Insert marker
Marker marker = new Marker(name, description, category, icon, getRecordingTrackId(), stats, trackPoint, photoUrl);
Uri uri = contentProviderUtils.insertMarker(marker);
return new Marker.Id(ContentUris.parseId(uri));
return trackRecordingManager.insertMarker(name, category, description, photoUrl);
}
/**
@@ -274,30 +233,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return null;
}
// Insert a track
Track track = new Track();
Uri uri = contentProviderUtils.insertTrack(track);
Track.Id trackId = new Track.Id(ContentUris.parseId(uri));
// Set recording status
Track.Id trackId = trackRecordingManager.start(handlerServer.createSegmentStartManual());
updateRecordingStatus(new RecordingStatus(trackId, false));
// Update database
track.setId(trackId);
TrackPoint segmentStartTrackPoint = handlerServer.createSegmentStartManual();
trackStatisticsUpdater = new TrackStatisticsUpdater();
insertTrackPoint(track, segmentStartTrackPoint);
//TODO Pass TrackPoint
track.setName(TrackNameUtils.getTrackName(this, trackId, segmentStartTrackPoint.getTime()));
String category = PreferencesUtils.getDefaultActivity(sharedPreferences, this);
track.setCategory(category);
track.setIcon(TrackIconUtils.getIconValue(this, category));
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
contentProviderUtils.updateTrack(track);
startRecording();
return trackId;
}
@@ -309,17 +248,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
* @param trackId the id of the track to be resumed.
*/
public void resumeTrack(Track.Id trackId) {
Track track = contentProviderUtils.getTrack(trackId);
if (track == null) {
Log.e(TAG, "Ignore resumeTrack. Track " + trackId.getId() + " does not exists.");
return;
}
// Sync the real time setting the stop time with current time.
track.getTrackStatistics().setStopTime(Instant.now());
trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics());
insertTrackPoint(track, handlerServer.createSegmentStartManual());
handlerServer.resetSensorData();
trackRecordingManager.resume(trackId, handlerServer.createSegmentStartManual());
// Set recording status
updateRecordingStatus(new RecordingStatus(trackId, false));
@@ -334,31 +264,18 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return;
}
// Set recording status
updateRecordingStatus(new RecordingStatus(getRecordingTrackId(), false));
// Update database
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics());
insertTrackPoint(track, handlerServer.createSegmentStartManual());
startRecording();
resumeTrack(getRecordingTrackId());
}
/**
* Common code for starting a new track, resuming a track, or restarting after phone reboot.
* Common code for starting a new track or resuming a track.
*/
private void startRecording() {
// Update instance variables
handler.postDelayed(updateRecordingData, RECORDING_DATA_UPDATE_INTERVAL.toMillis());
lastTrackPoint = null;
isIdle = false;
startGps();
handlerServer.resetSensorData();
// Restore periodic tasks
voiceExecutor.restore();
}
@@ -390,20 +307,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
updateRecordingStatus(STATUS_DEFAULT);
if (!wasPause) {
// Update database
Track track = contentProviderUtils.getTrack(trackId);
if (track != null) {
if (lastTrackPoint != null) {
insertTrackPointIfNewer(track, lastTrackPoint);
}
TrackPoint segmentEnd = handlerServer.createSegmentEnd();
insertTrackPoint(track, segmentEnd);
}
trackRecordingManager.end(handlerServer);
}
Track track = contentProviderUtils.getTrack(trackId);
ExportUtils.postWorkoutExport(this, track, new ExportServiceResultReceiver(new Handler(), this));
ExportUtils.postWorkoutExport(this, trackId, new ExportServiceResultReceiver(new Handler(), this));
endRecording(true);
}
@@ -418,14 +325,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
// Set recording status
updateRecordingStatus(new RecordingStatus(getRecordingTrackId(), true));
// Update database
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
if (track != null) {
if (lastTrackPoint != null) {
insertTrackPointIfNewer(track, lastTrackPoint);
}
insertTrackPoint(track, handlerServer.createSegmentEnd());
}
trackRecordingManager.pause(handlerServer);
endRecording(false);
@@ -449,8 +349,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
voiceExecutor.shutdown();
// Update instance variables
lastTrackPoint = null;
handlerServer.stop();
stopGps(trackStopped);
@@ -476,23 +374,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
}
}
/**
* Gets the last valid track point in the current segment.
*
* @param trackId the track id
* @return the location or null
*/
private TrackPoint getLastValidTrackPointInCurrentSegment(Track.Id trackId) {
if (!currentSegmentHasTrackPoint()) {
return null;
}
return contentProviderUtils.getLastValidTrackPoint(trackId);
}
private boolean currentSegmentHasTrackPoint() {
return lastTrackPoint != null;
}
@Override
public void newTrackPoint(TrackPoint trackPoint, Distance thresholdHorizontalAccuracy) {
if (!isRecording() || isPaused()) {
@@ -500,73 +381,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return;
}
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
if (track == null) {
Log.w(TAG, "Ignore newTrackPoint. No track.");
return;
}
notificationManager.updateTrackPoint(this, track.getTrackStatistics(), trackPoint, thresholdHorizontalAccuracy);
//TODO Figure out how to avoid loading the lastValidTrackPoint from the database
TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
//Storing trackPoint
// Always insert the first segment location
if (!currentSegmentHasTrackPoint()) {
insertTrackPoint(track, trackPoint);
lastTrackPoint = trackPoint;
return;
}
Distance distanceToLastTrackLocation = trackPoint.distanceToPrevious(lastValidTrackPoint);
if (distanceToLastTrackLocation.greaterThan(maxRecordingDistance)) {
insertTrackPointIfNewer(track, lastTrackPoint);
trackPoint.setType(TrackPoint.Type.SEGMENT_START_AUTOMATIC);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
if (trackPoint.hasSensorData() || distanceToLastTrackLocation.greaterOrEqualThan(recordingDistanceInterval)) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
if (!isIdle && !trackPoint.isMoving()) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = true;
lastTrackPoint = trackPoint;
return;
}
if (isIdle && trackPoint.isMoving()) {
insertTrackPointIfNewer(track, lastTrackPoint);
insertTrackPoint(track, trackPoint);
isIdle = false;
lastTrackPoint = trackPoint;
return;
}
Log.d(TAG, "Not recording TrackPoint, idle");
lastTrackPoint = trackPoint;
trackRecordingManager.onNewTrackPoint(trackPoint, thresholdHorizontalAccuracy);
notificationManager.updateTrackPoint(this, trackRecordingManager.getTrackStatistics(), trackPoint, thresholdHorizontalAccuracy);
voiceExecutor.update();
}
@Override
@@ -579,46 +396,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
}
}
/**
* Inserts a trackPoint if this trackPoint is different than lastValidTrackPoint.
*
* @param track the track
* @param trackPoint the trackPoint
*/
private void insertTrackPointIfNewer(@NonNull Track track, @NonNull TrackPoint trackPoint) {
TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
if (lastValidTrackPoint != null && trackPoint.getTime().equals(lastValidTrackPoint.getTime())) {
// Do not insert if inserted already
Log.w(TAG, "Ignore insertTrackPoint. trackPoint time same as last valid track point time.");
return;
}
insertTrackPoint(track, trackPoint);
}
/**
* Inserts a trackPoint.
*
* @param track the track
* @param trackPoint the trackPoint
*/
private void insertTrackPoint(@NonNull Track track, @NonNull TrackPoint trackPoint) {
try {
contentProviderUtils.insertTrackPoint(trackPoint, track.getId());
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
contentProviderUtils.updateTrack(track);
} catch (SQLiteException e) {
/*
* Insert failed, most likely because of SqlLite error code 5 (SQLite_BUSY).
* This is expected to happen extremely rarely (if our listener gets invoked twice at about the same time).
*/
Log.w(TAG, "SQLiteException", e);
}
voiceExecutor.update();
}
private void showNotification(boolean isGpsStarted) {
if (isRecording()) {
Intent intent = IntentUtils.newIntent(this, TrackRecordingActivity.class)
@@ -667,7 +444,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
Log.w(TAG, "Currently not recording; cannot update data.");
return;
}
Track track = contentProviderUtils.getTrack(recordingStatus.getTrackId());
// Compute temporary track statistics using sensorData and update time.
@@ -678,15 +454,11 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
return;
}
//TODO This somehow should happen in the HandlerServer as we create a new TrackPoint.
TrackStatisticsUpdater tmpTrackStatisticsUpdater = new TrackStatisticsUpdater(trackStatisticsUpdater);
Pair<TrackPoint, SensorDataSet> current = localHandlerServer.createCurrentTrackPoint(lastTrackPoint);
Pair<Track, Pair<TrackPoint, SensorDataSet>> data = trackRecordingManager.get(handlerServer);
TrackPoint trackPoint = data.second.first;
egm2008CorrectionManager.correctAltitude(this, trackPoint);
egm2008CorrectionManager.correctAltitude(this, current.first);
tmpTrackStatisticsUpdater.addTrackPoint(current.first, recordingDistanceInterval);
track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics());
recordingDataObservable.postValue(new RecordingData(track, current.first, current.second));
recordingDataObservable.postValue(new RecordingData(data.first, trackPoint, data.second.second));
}
public LiveData<RecordingStatus> getRecordingStatusObservable() {
@@ -37,6 +37,8 @@ public interface PeriodicTask {
*
* @param trackRecordingService the track recording service
*/
@Deprecated
//TODO Pass actual data instead of TrackRecordingService
void run(@NonNull TrackRecordingService trackRecordingService);
/**
@@ -28,13 +28,13 @@ public class ExportUtils {
private static final String TAG = ExportUtils.class.getSimpleName();
public static void postWorkoutExport(Context context, Track track, ExportServiceResultReceiver resultReceiver) {
public static void postWorkoutExport(Context context, Track.Id trackId, ExportServiceResultReceiver resultReceiver) {
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
if (PreferencesUtils.shouldInstantExportAfterWorkout(sharedPreferences, context)) {
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(sharedPreferences, context);
DocumentFile directory = PreferencesUtils.getDefaultExportDirectoryUri(sharedPreferences, context);
ExportService.enqueue(context, resultReceiver, track.getId(), trackFileFormat, directory.getUri());
ExportService.enqueue(context, resultReceiver, trackId, trackFileFormat, directory.getUri());
}
}