forked from upstream-mirrors/OpenTracks
@@ -33,6 +33,8 @@ import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.app.TaskStackBuilder;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -74,6 +76,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
|
||||
private static final String TAG = TrackRecordingService.class.getSimpleName();
|
||||
|
||||
public static final RecordingStatus STATUS_DEFAULT = new RecordingStatus(null, false);
|
||||
public static final GpsStatusValue STATUS_GPS_DEFAULT = GpsStatusValue.GPS_NONE;
|
||||
|
||||
// The following variables are set in onCreate:
|
||||
private ContentProviderUtils contentProviderUtils;
|
||||
private PeriodicTaskExecutor voiceExecutor;
|
||||
@@ -119,12 +124,18 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
|
||||
private HandlerServer handlerServer;
|
||||
|
||||
private final TrackRecordingServiceStatus serviceStatus = new TrackRecordingServiceStatus();
|
||||
private RecordingStatus recordingStatus;
|
||||
private MutableLiveData<RecordingStatus> recordingStatusObservable;
|
||||
private MutableLiveData<GpsStatusValue> gpsStatusObservable;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
recordingStatusObservable = new MutableLiveData<>();
|
||||
updateRecordingStatus(STATUS_DEFAULT);
|
||||
gpsStatusObservable = new MutableLiveData<>(STATUS_GPS_DEFAULT);
|
||||
|
||||
handlerServer = new HandlerServer(this);
|
||||
|
||||
contentProviderUtils = new ContentProviderUtils(this);
|
||||
@@ -149,8 +160,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
serviceStatus.onStop();
|
||||
|
||||
handlerServer.stop(this);
|
||||
handlerServer = null;
|
||||
|
||||
@@ -181,19 +190,22 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
// This should be the next to last operation
|
||||
wakeLock = SystemUtils.releaseWakeLock(wakeLock);
|
||||
|
||||
recordingStatusObservable = null;
|
||||
gpsStatusObservable = null;
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
return serviceStatus.isRecording();
|
||||
return recordingStatus.isRecording();
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return serviceStatus.getRecordingTrackPaused();
|
||||
return recordingStatus.isPaused();
|
||||
}
|
||||
|
||||
public Track.Id getRecordingTrackId() {
|
||||
return serviceStatus.getRecordingTrackId();
|
||||
return recordingStatus.getTrackId();
|
||||
}
|
||||
|
||||
public TrackStatistics getTrackStatistics() {
|
||||
@@ -223,14 +235,14 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
|
||||
if (name == null) {
|
||||
Integer nextMarkerNumber = contentProviderUtils.getNextMarkerNumber(serviceStatus.getRecordingTrackId());
|
||||
Integer nextMarkerNumber = contentProviderUtils.getNextMarkerNumber(getRecordingTrackId());
|
||||
if (nextMarkerNumber == null) {
|
||||
nextMarkerNumber = 1;
|
||||
}
|
||||
name = getString(R.string.marker_name_format, nextMarkerNumber + 1);
|
||||
}
|
||||
|
||||
TrackPoint trackPoint = getLastValidTrackPointInCurrentSegment(serviceStatus.getRecordingTrackId());
|
||||
TrackPoint trackPoint = getLastValidTrackPointInCurrentSegment(getRecordingTrackId());
|
||||
if (trackPoint == null) {
|
||||
Log.i(TAG, "Could not create a marker as trackPoint is unknown.");
|
||||
return null;
|
||||
@@ -244,7 +256,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
TrackStatistics stats = trackStatisticsUpdater.getTrackStatistics();
|
||||
|
||||
// Insert marker
|
||||
Marker marker = new Marker(name, description, category, icon, serviceStatus.getRecordingTrackId(), stats, trackPoint, photoUrl);
|
||||
Marker marker = new Marker(name, description, category, icon, getRecordingTrackId(), stats, trackPoint, photoUrl);
|
||||
Uri uri = contentProviderUtils.insertMarker(marker);
|
||||
return new Marker.Id(ContentUris.parseId(uri));
|
||||
}
|
||||
@@ -266,7 +278,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
Track.Id trackId = new Track.Id(ContentUris.parseId(uri));
|
||||
|
||||
// Set recording status
|
||||
serviceStatus.onChange(trackId, false);
|
||||
updateRecordingStatus(new RecordingStatus(trackId, false));
|
||||
|
||||
// Update database
|
||||
track.setId(trackId);
|
||||
@@ -308,7 +320,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
insertTrackPoint(track, TrackPoint.createSegmentStartManual());
|
||||
|
||||
// Set recording status
|
||||
serviceStatus.onChange(trackId, false);
|
||||
updateRecordingStatus(new RecordingStatus(trackId, false));
|
||||
|
||||
startRecording();
|
||||
}
|
||||
@@ -321,10 +333,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
|
||||
// Set recording status
|
||||
serviceStatus.onChange(false);
|
||||
updateRecordingStatus(new RecordingStatus(getRecordingTrackId(), false));
|
||||
|
||||
// Update database
|
||||
Track track = contentProviderUtils.getTrack(serviceStatus.getRecordingTrackId());
|
||||
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
|
||||
if (track != null) {
|
||||
insertTrackPoint(track, TrackPoint.createSegmentStartManual());
|
||||
}
|
||||
@@ -373,10 +385,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
|
||||
// Need to remember the recordingTrackId before setting it to null
|
||||
boolean wasPause = isPaused();
|
||||
Track.Id trackId = serviceStatus.getRecordingTrackId();
|
||||
Track.Id trackId = getRecordingTrackId();
|
||||
|
||||
// Set recording status
|
||||
serviceStatus.onChange(null, true);
|
||||
updateRecordingStatus(STATUS_DEFAULT);
|
||||
|
||||
if (!wasPause) {
|
||||
// Update database
|
||||
@@ -404,10 +416,10 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
|
||||
// Set recording status
|
||||
serviceStatus.onChange(true);
|
||||
updateRecordingStatus(new RecordingStatus(getRecordingTrackId(), true));
|
||||
|
||||
// Update database
|
||||
Track track = contentProviderUtils.getTrack(serviceStatus.getRecordingTrackId());
|
||||
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
|
||||
if (track != null) {
|
||||
if (lastTrackPoint != null) {
|
||||
insertTrackPointIfNewer(track, lastTrackPoint);
|
||||
@@ -490,7 +502,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
return;
|
||||
}
|
||||
|
||||
Track track = contentProviderUtils.getTrack(serviceStatus.getRecordingTrackId());
|
||||
Track track = contentProviderUtils.getTrack(getRecordingTrackId());
|
||||
if (track == null) {
|
||||
Log.w(TAG, "Ignore newTrackPoint. No track.");
|
||||
return;
|
||||
@@ -564,17 +576,8 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
@Override
|
||||
public void newGpsStatus(GpsStatusValue gpsStatusValue) {
|
||||
notificationManager.updateContent(getString(gpsStatusValue.message));
|
||||
serviceStatus.onChange(gpsStatusValue);
|
||||
}
|
||||
|
||||
public void addListener(@NonNull TrackRecordingServiceStatus.Listener listener) {
|
||||
serviceStatus.addListener(listener);
|
||||
}
|
||||
|
||||
//TODO Check that this is used everywhere, where addListener is called!
|
||||
//Otherwise, we keep objects in referenced and waste memory until this service instance is terminated.
|
||||
public void removeListener(@NonNull TrackRecordingServiceStatus.Listener listener) {
|
||||
serviceStatus.removeListener(listener);
|
||||
gpsStatusObservable.postValue(gpsStatusValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -666,7 +669,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
private void showNotification(boolean isGpsStarted) {
|
||||
if (isRecording()) {
|
||||
Intent intent = IntentUtils.newIntent(this, TrackRecordingActivity.class)
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, serviceStatus.getRecordingTrackId());
|
||||
.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, getRecordingTrackId());
|
||||
PendingIntent pendingIntent = TaskStackBuilder.create(this)
|
||||
.addParentStack(TrackRecordingActivity.class)
|
||||
.addNextIntent(intent)
|
||||
@@ -702,8 +705,18 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
this.altitudeSumManager = altitudeSumManager;
|
||||
}
|
||||
|
||||
public GpsStatusValue getGpsStatus() {
|
||||
return handlerServer.getGpsStatus();
|
||||
public LiveData<GpsStatusValue> getGpsStatusObservable() {
|
||||
return gpsStatusObservable;
|
||||
}
|
||||
|
||||
public LiveData<RecordingStatus> getRecordingStatusObservable() {
|
||||
return recordingStatusObservable;
|
||||
}
|
||||
|
||||
private void updateRecordingStatus(RecordingStatus status) {
|
||||
Log.i(TAG, "new status " + recordingStatus + " -> " + status);
|
||||
recordingStatus = status;
|
||||
recordingStatusObservable.postValue(recordingStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -717,6 +730,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Binder extends android.os.Binder {
|
||||
|
||||
private Binder() {
|
||||
@@ -727,4 +741,51 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
return TrackRecordingService.this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RecordingStatus {
|
||||
private final Track.Id trackId;
|
||||
private final boolean paused;
|
||||
|
||||
public RecordingStatus(Track.Id trackId, boolean paused) {
|
||||
this.trackId = trackId;
|
||||
this.paused = paused;
|
||||
}
|
||||
|
||||
public Track.Id getTrackId() {
|
||||
return trackId;
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
return trackId != null;
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return paused;
|
||||
}
|
||||
|
||||
public boolean isRecordingAndNotPaused() {
|
||||
return isRecording() && !isPaused();
|
||||
}
|
||||
|
||||
public RecordingStatus pause() {
|
||||
return new RecordingStatus(getTrackId(), true);
|
||||
}
|
||||
|
||||
public RecordingStatus record(@NonNull Track.Id track) {
|
||||
return new RecordingStatus(trackId, false);
|
||||
}
|
||||
|
||||
public RecordingStatus stop() {
|
||||
return STATUS_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RecordingStatus{" +
|
||||
"trackId=" + trackId +
|
||||
", paused=" + paused +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package de.dennisguse.opentracks.services;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.Track;
|
||||
import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
|
||||
|
||||
/**
|
||||
* This class handles the status of the recording service.
|
||||
* Also offer an interface through which to know the recording Track.Id, pause status and GPS status.
|
||||
*/
|
||||
public class TrackRecordingServiceStatus {
|
||||
|
||||
private Track.Id recordingTrackId;
|
||||
private boolean recordingTrackPaused;
|
||||
|
||||
private final List<Listener> listeners = new ArrayList<>();
|
||||
|
||||
void addListener(@NonNull Listener listener) {
|
||||
if (this.listeners.contains(listener)) {
|
||||
return;
|
||||
}
|
||||
this.listeners.add(listener);
|
||||
listener.onTrackRecordingId(recordingTrackId);
|
||||
listener.onTrackRecordingPaused(recordingTrackPaused);
|
||||
}
|
||||
|
||||
void removeListener(@NonNull Listener listener) {
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
public boolean getRecordingTrackPaused() {
|
||||
return this.recordingTrackPaused;
|
||||
}
|
||||
|
||||
public Track.Id getRecordingTrackId() {
|
||||
return this.recordingTrackId;
|
||||
}
|
||||
|
||||
public void onStop() {
|
||||
for (Listener listener : listeners) {
|
||||
listener.onGpsStatus(GpsStatusValue.GPS_NONE);
|
||||
listener.onTrackRecordingId(null);
|
||||
listener.onTrackRecordingPaused(true);
|
||||
}
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
return recordingTrackId != null;
|
||||
}
|
||||
|
||||
void onChange(Track.Id trackId, boolean paused) {
|
||||
recordingTrackId = trackId;
|
||||
recordingTrackPaused = paused;
|
||||
for (Listener listener : listeners) {
|
||||
listener.onTrackRecordingId(recordingTrackId);
|
||||
listener.onTrackRecordingPaused(recordingTrackPaused);
|
||||
}
|
||||
}
|
||||
|
||||
void onChange(boolean paused) {
|
||||
recordingTrackPaused = paused;
|
||||
for (Listener listener : listeners) {
|
||||
listener.onTrackRecordingPaused(recordingTrackPaused);
|
||||
}
|
||||
}
|
||||
|
||||
void onChange(GpsStatusValue statusValue) {
|
||||
for (Listener listener : listeners) {
|
||||
listener.onGpsStatus(statusValue);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
default void onGpsStatus(GpsStatusValue newValue) {}
|
||||
default void onTrackRecordingPaused(boolean paused) {}
|
||||
default void onTrackRecordingId(Track.Id trackId) {}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,8 @@ public enum GpsStatusValue {
|
||||
this.icon = icon;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public boolean isGpsStarted() {
|
||||
return this != GpsStatusValue.GPS_NONE && this != GpsStatusValue.GPS_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user