diff --git a/README.md b/README.md
index 0310c367a..5602a7555 100644
--- a/README.md
+++ b/README.md
@@ -130,6 +130,7 @@ The API can be invoked by sending an explicit Intent to start an activity.
`Class`:
* **Start a recording:** `de.dennisguse.opentracks.publicapi.StartRecording`
+* **Start a recording:** `de.dennisguse.opentracks.publicapi.StopRecording`
For testing via adb: `adb shell am start -n "package/class"`
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index c87033f84..4726f5997 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -77,14 +77,14 @@ limitations under the License.
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
index 1e1c4382e..e7683fc73 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
-import android.graphics.Color;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.location.LocationManager;
import android.os.Bundle;
@@ -139,7 +138,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
private MenuItem searchMenuItem;
private MenuItem startGpsMenuItem;
- private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
+ private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
service.getRecordingStatusObservable()
.observe(TrackListActivity.this, this::onRecordingStatusChanged);
@@ -167,16 +166,15 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
viewBinding.trackList.setEmptyView(viewBinding.trackListEmptyView);
- viewBinding.trackList.setOnItemClickListener((parent, view, position, trackId) -> {
- if (recordingStatus.isRecording() && trackId == recordingStatus.getTrackId().getId()) {
+ viewBinding.trackList.setOnItemClickListener((parent, view, position, trackIdId) -> {
+ Track.Id trackId = new Track.Id(trackIdId);
+ Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
+ .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, trackId);
+ if (recordingStatus.isRecording() && trackId.equals(recordingStatus.getTrackId())) {
// Is recording -> open record activity.
- Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class)
- .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, new Track.Id(trackId));
startActivity(newIntent);
} else {
// Not recording -> open detail activity.
- Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordedActivity.class)
- .putExtra(TrackRecordedActivity.EXTRA_TRACK_ID, new Track.Id(trackId));
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
this,
new Pair<>(view.findViewById(R.id.list_item_icon), TrackRecordedActivity.VIEW_TRACK_ICON));
@@ -230,8 +228,15 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
// Not Recording -> Recording
updateGpsMenuItem(false, true);
- Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
- startActivity(newIntent);
+ new TrackRecordingServiceConnection((service, connection) -> {
+ Track.Id trackId = service.startNewTrack();
+
+ Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class);
+ newIntent.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
+ startActivity(newIntent);
+
+ connection.unbind(this);
+ }).startAndBind(this);
});
viewBinding.trackListFabAction.setOnLongClickListener((view) -> {
if (!recordingStatus.isRecording()) {
diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
index c0526bbed..db0073335 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
@@ -79,7 +79,7 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
private TrackRecordingServiceConnection trackRecordingServiceConnection;
- private final TrackRecordingServiceConnection.Callback bindCallback = service -> service.getRecordingStatusObservable()
+ private final TrackRecordingServiceConnection.Callback bindCallback = (service, unused) -> service.getRecordingStatusObservable()
.observe(TrackRecordedActivity.this, this::onRecordingStatusChanged);
@Override
@@ -203,11 +203,17 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
}
if (item.getItemId() == R.id.track_detail_resume_track) {
- Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
- .putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
- startActivity(newIntent);
- overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
- finish();
+ new TrackRecordingServiceConnection((service, connection) -> {
+ service.resumeTrack(trackId);
+
+ Intent newIntent = IntentUtils.newIntent(TrackRecordedActivity.this, TrackRecordingActivity.class)
+ .putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId);
+ startActivity(newIntent);
+ overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
+
+ connection.unbind(this);
+ finish();
+ }).startAndBind(this);
return true;
}
diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
index b64bf85be..3871ba042 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java
@@ -57,8 +57,6 @@ import de.dennisguse.opentracks.util.TrackUtils;
* @author Leif Hendrik Wilden
* @author Rodrigo Damazio
*/
-//NOTE: This activity does NOT react to preference changes of R.string.recording_track_id_key.
-//This mode of communication should be removed anyhow.
public class TrackRecordingActivity extends AbstractActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, TrackDataHubInterface {
public static final String EXTRA_TRACK_ID = "track_id";
@@ -76,13 +74,11 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
private TrackRecordingBinding viewBinding;
- // Initialized from Intent; if a new track recording is started, a new TrackId will be provided by TrackRecordingService
- @Deprecated
private Track.Id trackId;
private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT;
- private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
+ private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
service.getRecordingStatusObservable()
.observe(TrackRecordingActivity.this, this::onRecordingStatusChanged);
@@ -90,18 +86,12 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
.observe(TrackRecordingActivity.this, this::onGpsStatusChanged);
if (!service.isRecording()) {
- if (trackId == null) {
- // trackId isn't initialized -> leads a new recording.
- trackId = service.startNewTrack();
- } else {
- // trackId is initialized -> resumes the track.
- service.resumeTrack(trackId);
- }
-
- // A recording track is on.
- trackDataHub.loadTrack(trackId);
- trackDataHub.setRecordingStatus(recordingStatus);
+ finish();
+ return;
}
+
+ trackDataHub.loadTrack(trackId);
+ trackDataHub.setRecordingStatus(recordingStatus);
};
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> {
@@ -123,17 +113,14 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
contentProviderUtils = new ContentProviderUtils(this);
- trackId = null;
- if (savedInstanceState != null) {
- //Activity was recreated.
- trackId = savedInstanceState.getParcelable(EXTRA_TRACK_ID);
- } else {
- // Resume a track
- trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
- if (trackId != null && contentProviderUtils.getTrack(trackId) == null) {
- Log.w(TAG, "TrackId does not exists; cannot continue the recording.");
- finish();
- }
+
+ trackId = getIntent().getParcelableExtra(EXTRA_TRACK_ID);
+ if (trackId == null) {
+ throw new RuntimeException("TrackId is mandatory");
+ }
+ if (contentProviderUtils.getTrack(trackId) == null) {
+ Log.w(TAG, "TrackId does not exists; cannot continue the recording.");
+ finish();
}
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback);
@@ -240,7 +227,6 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(CURRENT_TAB_TAG_KEY, viewBinding.trackDetailActivityViewPager.getCurrentItem());
- outState.putParcelable(EXTRA_TRACK_ID, trackId);
}
@Override
@@ -377,6 +363,9 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
}
private void onRecordingStatusChanged(RecordingStatus status) {
+ if (!status.isRecording()) {
+ finish();
+ }
recordingStatus = status;
trackDataHub.setRecordingStatus(recordingStatus);
@@ -415,7 +404,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc
.make(viewBinding.trackRecordingCoordinatorLayout,
getString(R.string.gps_recording_status, getString(gpsStatusValue.message), getString(R.string.gps_recording_without_signal)),
Snackbar.LENGTH_INDEFINITE)
- .setAction(getString(R.string.generic_dismiss), v -> {});
+ .setAction(getString(R.string.generic_dismiss), v -> {
+ });
snackbar.show();
}
}
\ No newline at end of file
diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
index a0de16c8b..c8d1c1f56 100644
--- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
@@ -77,7 +77,7 @@ public class StatisticsRecordingFragment extends Fragment {
}
};
- private final TrackRecordingServiceConnection.Callback bindChangedCallback = service -> {
+ private final TrackRecordingServiceConnection.Callback bindChangedCallback = (service, unused) -> {
service.getRecordingDataObservable()
.observe(StatisticsRecordingFragment.this, this::onRecordingDataChanged);
};
diff --git a/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java b/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java
index 153a95311..6d47fd76e 100644
--- a/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java
@@ -16,27 +16,25 @@ public abstract class AbstractAPIActivity extends AppCompatActivity {
private final String TAG = AbstractAPIActivity.class.getSimpleName();
- private final TrackRecordingServiceConnection.Callback serviceConnectedCallback = service -> {
+ private final TrackRecordingServiceConnection.Callback serviceConnectedCallback = (service, connection) -> {
if (!isFinishing() && !isDestroyed()) {
execute(service);
}
if (isPostExecuteStopService()) {
- AbstractAPIActivity.this.trackRecordingServiceConnection.unbindAndStop(AbstractAPIActivity.this);
+ connection.unbindAndStop(AbstractAPIActivity.this);
} else {
- AbstractAPIActivity.this.trackRecordingServiceConnection.unbind(AbstractAPIActivity.this);
+ connection.unbind(AbstractAPIActivity.this);
}
finish();
};
- private TrackRecordingServiceConnection trackRecordingServiceConnection;
-
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (PreferencesUtils.isPublicAPIenabled()) {
Log.i(TAG, "Received and trying to execute requested action.");
- trackRecordingServiceConnection = new TrackRecordingServiceConnection(serviceConnectedCallback);
- trackRecordingServiceConnection.startAndBind(this);
+ new TrackRecordingServiceConnection(serviceConnectedCallback)
+ .startAndBind(this);
} else {
Toast.makeText(this, getString(R.string.settings_public_api_disabled_toast), Toast.LENGTH_LONG).show();
Log.w(TAG, "Public API is disabled; ignoring request.");
@@ -44,12 +42,6 @@ public abstract class AbstractAPIActivity extends AppCompatActivity {
}
}
- @Override
- protected void onDestroy() {
- super.onDestroy();
- trackRecordingServiceConnection = null;
- }
-
protected abstract void execute(TrackRecordingService service);
protected abstract boolean isPostExecuteStopService();
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceConnection.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceConnection.java
index 360679482..ee7c20254 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceConnection.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceConnection.java
@@ -92,15 +92,10 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
return;
}
if (callback != null) {
- callback.onConnected(trackRecordingService);
+ callback.onConnected(trackRecordingService, this);
}
}
- /**
- * Resumes the track recording service connection.
- *
- * @param context the context
- */
public void startConnection(@NonNull Context context) {
if (trackRecordingService != null) {
// Service is already started and bound.
@@ -115,6 +110,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
/**
* Unbinds the service (but leave it running).
*/
+ //TODO This is often called for one-shot operations and should be refactored as unbinding is required.
public void unbind(Context context) {
try {
context.unbindService(this);
@@ -141,7 +137,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
trackRecordingService = value;
if (callback != null) {
if (value != null) {
- callback.onConnected(value);
+ callback.onConnected(value, this);
} else {
callback.onDisconnected();
}
@@ -214,7 +210,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
}
public interface Callback {
- void onConnected(TrackRecordingService service);
+ void onConnected(TrackRecordingService service, TrackRecordingServiceConnection connection);
default void onDisconnected() {
}
diff --git a/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java b/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
index 7913f5548..2a023d36e 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/MainSettingsFragment.java
@@ -18,7 +18,7 @@ public class MainSettingsFragment extends PreferenceFragmentCompat {
private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT;
private TrackRecordingServiceConnection trackRecordingServiceConnection;
private final TrackRecordingServiceConnection.Callback bindServiceCallback =
- service -> service.getRecordingStatusObservable()
+ (service, unused) -> service.getRecordingStatusObservable()
.observe(MainSettingsFragment.this, this::onRecordingStatusChanged);
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
index 5bc0c2a85..eadcec138 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
@@ -71,7 +71,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
private TrackRecordingServiceConnection trackRecordingServiceConnection;
- private final TrackRecordingServiceConnection.Callback bindCallback = service -> service.getRecordingStatusObservable()
+ private final TrackRecordingServiceConnection.Callback bindCallback = (service, unused) -> service.getRecordingStatusObservable()
.observe(MarkerListActivity.this, this::onRecordingStatusChanged);
// Callback when an item is selected in the contextual action mode