From 522d9ebe2ec861c3989f0ce438bbadf3ab8f4974 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 19 Dec 2024 18:39:53 +0100 Subject: [PATCH] Public API: allow marker creation. Fixes #2031. --- README.md | 17 +++++++++-------- .../data/CustomContentProviderUtilsTest.java | 18 +++++++++--------- src/main/AndroidManifest.xml | 8 ++++++++ .../opentracks/data/ContentProviderUtils.java | 9 ++++----- .../publicapi/AbstractAPIActivity.java | 2 +- .../opentracks/publicapi/CreateMarker.java | 16 ++++++++++++++++ .../publicapi/CreateMarkerActivity.java | 2 +- .../publicapi/ShowMarkerActivity.java | 2 +- .../services/TrackRecordingService.java | 16 ++++++++++++++++ 9 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/publicapi/CreateMarker.java diff --git a/README.md b/README.md index a8eac7ba3d..65b79d3b14 100644 --- a/README.md +++ b/README.md @@ -109,19 +109,20 @@ The API can be invoked by sending an explicit Intent to start an activity. * Debug: `de.dennisguse.opentracks.debug` * Nightly: `de.dennisguse.opentracks.nightly` -`Class`: - +`Classes`: * **Start a recording:** `de.dennisguse.opentracks.publicapi.StartRecording` + * Set track data: `TRACK_NAME`, `TRACK_DESCRIPTION`, `TRACK_CATEGORY`, and `TRACK_ICON` ( + non-localized identifier + see [/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38](/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38)). + NOTE: if `TRACK_ICON` is not present, `TRACK_CATEGORY` will be used to determine the icon ( + localized). + * Send recorded data to another application via _Dashboard API_: `STATS_TARGET_PACKAGE` and + `STATS_TARGET_CLASS` * **Stop a recording:** `de.dennisguse.opentracks.publicapi.StopRecording` +* **Create a marker:** `de.dennisguse.opentracks.publicapi.CreateMarker` For testing via adb: `adb shell am start -e someParameter someValue -n "package/class"` -`StartRecording` supports the following parameters: - -* Set track data: `TRACK_NAME`, `TRACK_DESCRIPTION`, `TRACK_CATEGORY`, and `TRACK_ICON` (non-localized identifier see [/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38](/src/main/java/de/dennisguse/opentracks/util/TrackIconUtils.java#L38)). - NOTE: if `TRACK_ICON` is not present, `TRACK_CATEGORY` will be used to determine the icon (localized). -* Send recorded data to another application via _Dashboard API_: `STATS_TARGET_PACKAGE` and `STATS_TARGET_CLASS` - The Public API is disabled by default to protect the user's privacy, but it can easily be enabled in the settings. ## File formats compatibility with open-source software diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index 94dc1238d6..6f1cdeea94 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -482,7 +482,7 @@ public void testDeleteMarker_onlyOneMarker() { assertEquals(contentProviderUtils.getMarkers(trackId).size(), 1); // Get marker id that needs to delete. - Marker.Id marker1Id = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker1))); + Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1); // Delete contentProviderUtils.deleteMarker(context, marker1Id); @@ -509,7 +509,7 @@ public void testDeleteMarker_onlyOneMarkerWithPhotoUrl() throws IOException { assertEquals(contentProviderUtils.getMarkers(trackId).size(), 1); // Get marker id that needs to delete. - Marker.Id marker1Id = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker1))); + Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1); // Check marker has photo and it's in the external storage. assertTrue(marker1.hasPhoto()); @@ -553,11 +553,11 @@ public void testDeleteMarker_hasNextMarker() { // Insert at first. Marker marker1 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId)); marker1.setDescription(MOCK_DESC); - Marker.Id marker1Id = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker1))); + Marker.Id marker1Id = contentProviderUtils.insertMarker(marker1); Marker marker2 = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId)); marker2.setDescription(MOCK_DESC); - Marker.Id marker2Id = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker2))); + Marker.Id marker2Id = contentProviderUtils.insertMarker(marker2); // Delete assertNotNull(contentProviderUtils.getMarker(marker1Id)); @@ -598,7 +598,7 @@ public void testInsertAndGetMarker() { Marker marker = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId)); marker.setDescription(TEST_DESC); - Marker.Id markerId = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker))); + Marker.Id markerId = contentProviderUtils.insertMarker(marker); assertEquals(TEST_DESC, contentProviderUtils.getMarker(markerId).getDescription()); } @@ -614,7 +614,7 @@ public void testUpdateMarker() { // Insert at first. Marker marker = new Marker(trackId, contentProviderUtils.getLastValidTrackPoint(trackId)); marker.setDescription(TEST_DESC); - Marker.Id markerId = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker))); + Marker.Id markerId = contentProviderUtils.insertMarker(marker); // Update marker = contentProviderUtils.getMarker(markerId); @@ -638,7 +638,7 @@ public void testUpdateMarker_withPhoto() throws IOException { TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId); Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint); marker.setDescription(TEST_DESC); - Marker.Id markerId = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker))); + Marker.Id markerId = contentProviderUtils.insertMarker(marker); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.id()); assertTrue(dir.exists()); @@ -673,7 +673,7 @@ public void testUpdateMarker_delPhotoAndDir() throws IOException { TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId); Marker marker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint); marker.setDescription(TEST_DESC); - Marker.Id markerId = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker))); + Marker.Id markerId = contentProviderUtils.insertMarker(marker); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.id()); assertTrue(dir.exists()); @@ -709,7 +709,7 @@ public void testUpdateMarker_delPhotoNotDir() throws IOException { marker.setDescription(TEST_DESC); Marker otherMarker = TestDataUtil.createMarkerWithPhoto(context, trackId, trackPoint); otherMarker.setDescription(TEST_DESC); - Marker.Id markerId = new Marker.Id(ContentUris.parseId(contentProviderUtils.insertMarker(marker))); + Marker.Id markerId = contentProviderUtils.insertMarker(marker); contentProviderUtils.insertMarker(otherMarker); File dir = new File(FileUtils.getPhotoDir(context), "" + trackId.id()); diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 9c5bf3d96b..fe18878073 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -98,6 +98,14 @@ limitations under the License. + + + + + getMarkers(Track.Id trackId) { return markers; } - /** - * @return the content provider URI of the inserted marker. - */ - public Uri insertMarker(@NonNull Marker marker) { + // TODO Merge with updateMarker + public Marker.Id insertMarker(@NonNull Marker marker) { marker.setId(null); - return contentResolver.insert(MarkerColumns.CONTENT_URI, createContentValues(marker)); + Uri uri = contentResolver.insert(MarkerColumns.CONTENT_URI, createContentValues(marker)); + return new Marker.Id(ContentUris.parseId(uri)); } private void deleteMarkerPhoto(Context context, Marker marker) { diff --git a/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java b/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java index a725cf6272..1bcb6b60c4 100644 --- a/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java +++ b/src/main/java/de/dennisguse/opentracks/publicapi/AbstractAPIActivity.java @@ -13,7 +13,7 @@ import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; import de.dennisguse.opentracks.settings.PreferencesUtils; -public abstract class AbstractAPIActivity extends AppCompatActivity { +abstract class AbstractAPIActivity extends AppCompatActivity { private final String TAG = AbstractAPIActivity.class.getSimpleName(); diff --git a/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarker.java b/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarker.java new file mode 100644 index 0000000000..c52e7a2239 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarker.java @@ -0,0 +1,16 @@ +package de.dennisguse.opentracks.publicapi; + +import de.dennisguse.opentracks.services.TrackRecordingService; + +public class CreateMarker extends AbstractAPIActivity { + + @Override + protected void execute(TrackRecordingService service) { + service.createMarker(); + } + + @Override + protected boolean isPostExecuteStopService() { + return false; + } +} diff --git a/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarkerActivity.java b/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarkerActivity.java index 5d9eff6cd0..8c1f8b27b8 100644 --- a/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarkerActivity.java +++ b/src/main/java/de/dennisguse/opentracks/publicapi/CreateMarkerActivity.java @@ -12,7 +12,7 @@ import de.dennisguse.opentracks.util.IntentUtils; /** - * Public API to creates a Marker for a given track with a given location + * INTERNAL: only meant for clients of OSMDashboard API. */ public class CreateMarkerActivity extends AppCompatActivity { diff --git a/src/main/java/de/dennisguse/opentracks/publicapi/ShowMarkerActivity.java b/src/main/java/de/dennisguse/opentracks/publicapi/ShowMarkerActivity.java index 9f01a5835d..e29b172c92 100644 --- a/src/main/java/de/dennisguse/opentracks/publicapi/ShowMarkerActivity.java +++ b/src/main/java/de/dennisguse/opentracks/publicapi/ShowMarkerActivity.java @@ -13,7 +13,7 @@ import de.dennisguse.opentracks.util.IntentUtils; /** - * Public api to show an existing marker + * INTERNAL: only meant for clients of OSMDashboard API. */ public class ShowMarkerActivity extends AppCompatActivity { diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index 4481a7f78c..a5b65f228c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -36,7 +36,9 @@ import java.io.StringWriter; import java.time.Duration; +import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; @@ -243,6 +245,20 @@ void stopSensors() { gpsStatusObservable.postValue(STATUS_GPS_DEFAULT); } + public Marker.Id createMarker() { + if (!isRecording()) { + return null; + } + + //TODO This contains some duplication to TrackRecodingActivity's Marker creation + TrackPoint trackPoint = trackRecordingManager.getLastStoredTrackPointWithLocation(); + if (trackPoint == null) { + return null; + } + Marker marker = new Marker(recordingStatus.trackId(), trackPoint); + return new ContentProviderUtils(this).insertMarker(marker); + } + @Override public boolean newTrackPoint(TrackPoint trackPoint, Distance thresholdHorizontalAccuracy) { if (!isRecording()) {