diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index 27c54e79c..6eb61c59b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -2,6 +2,7 @@ package de.dennisguse.opentracks.services; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.Intent; @@ -93,6 +94,41 @@ public class TrackRecordingServiceRecordingTest { service = startService(); } + @MediumTest + @Test + public void reCreate_not_recording() { + // given + TrackIdStorage.unset(context); + + assertFalse(service.isRecording()); + + // when + service.onStartCommand(null, 0, 1); + + // then + assertFalse(service.isRecording()); + } + + @MediumTest + @Test + public void reCreate_recording() { + // given + assertFalse(service.isRecording()); + Track.Id trackId = service.startNewTrack(); + assertTrue(service.isRecording()); + + // when (crash and restart) + service.onDestroy(); + service.onCreate(); + service.onStartCommand(null, 0, 1); + + // then + assertTrue(service.isRecording()); + assertEquals(trackId, service.getRecordingStatusObservable().getValue().trackId()); + + service.endCurrentTrack(); + } + @MediumTest @Test public void recording_startStop() { diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackIdStorage.java b/src/main/java/de/dennisguse/opentracks/services/TrackIdStorage.java new file mode 100644 index 000000000..db2bb75f9 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/services/TrackIdStorage.java @@ -0,0 +1,56 @@ +package de.dennisguse.opentracks.services; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import de.dennisguse.opentracks.data.models.Track; + +/** + * For handling restarts of TrackRecordingService: while recording, stores the {@link de.dennisguse.opentracks.data.models.Track.Id}. + */ +class TrackIdStorage { + + private final static String SHARED_PREFERENCE_NAME = "TrackRecordingService_pref"; + + private final static String KEY = "trackId_key"; + + private static SharedPreferences sharedPreferences; + + private static void init(Context context) { + if (sharedPreferences == null) { + sharedPreferences = context.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); + } + } + + @Nullable + public static Track.Id get(Context context) { + TrackIdStorage.init(context); + + long value = sharedPreferences.getLong(KEY, -1); + if (value < 0) { + return null; + } + + return new Track.Id(value); + } + + public static void set(Context context, @NonNull Track.Id trackId) { + TrackIdStorage.init(context); + + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putLong(KEY, trackId.id()); + editor.commit(); + } + + public static void unset(Context context) { + TrackIdStorage.init(context); + + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.remove(KEY); + editor.commit(); + } + +} diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index b7fc63040..8ca4c5a4a 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -86,7 +86,6 @@ public class TrackRecordingService extends Service implements TrackPointCreator. private MutableLiveData gpsStatusObservable; private MutableLiveData recordingDataObservable; - // The following variables are set when recording: private Handler handler; private TrackPointCreator trackPointCreator; @@ -119,9 +118,6 @@ public class TrackRecordingService extends Service implements TrackPointCreator. @Override public void onDestroy() { Log.d(TAG, "Destroying"); - if (isRecording()) { - endCurrentTrack(); - } if (trackPointCreator != null && trackPointCreator.isStarted()) { stopSensors(); } @@ -150,6 +146,16 @@ public class TrackRecordingService extends Service implements TrackPointCreator. @Override public int onStartCommand(Intent intent, int flags, int startId) { + if (intent == null) { + Log.i(TAG, "Service got killed and is restarting"); + + //Best guess: do we need to resume a recording? + Track.Id trackId = TrackIdStorage.get(this); + if (trackId != null) { + Log.i(TAG, "After restart: resuming recording for " + trackId); + resumeTrack(trackId); + } + } return START_STICKY; } @@ -167,9 +173,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. // Set recording status Track.Id trackId = trackRecordingManager.startNewTrack(); - updateRecordingStatus(RecordingStatus.record(trackId)); - - startRecording(); + startRecording(trackId); return trackId; } @@ -180,12 +184,13 @@ public class TrackRecordingService extends Service implements TrackPointCreator. } Log.i(TAG, "resumeTrack"); - updateRecordingStatus(RecordingStatus.record(trackId)); - - startRecording(); + startRecording(trackId); } - private void startRecording() { + private void startRecording(Track.Id trackId) { + updateRecordingStatus(RecordingStatus.record(trackId)); + TrackIdStorage.set(this, trackId); + startSensors(); voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics()); @@ -226,6 +231,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. updateRecordingStatus(STATUS_DEFAULT); trackRecordingManager.endCurrentTrack(); + TrackIdStorage.unset(this); stopUpdateRecordingData();