diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/share/DescriptionGeneratorTest.java
similarity index 88%
rename from src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java
rename to src/androidTest/java/de/dennisguse/opentracks/share/DescriptionGeneratorTest.java
index 613f52bd7..eaa0193c2 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/share/DescriptionGeneratorTest.java
@@ -14,7 +14,7 @@
* the License.
*/
-package de.dennisguse.opentracks.content;
+package de.dennisguse.opentracks.share;
import static org.junit.Assert.assertEquals;
@@ -82,18 +82,18 @@ public class DescriptionGeneratorTest {
+ "Description: -
"
+ "Total distance: 20.00 km (12.4 mi)
"
+ "Total time: 10:00
"
- + "Moving time: 05:00
"
- + "Average speed: 120.00 km/h (74.6 mi/h)
"
- + "Average moving speed: 240.00 km/h (149.1 mi/h)
"
- + "Max speed: 360.00 km/h (223.7 mi/h)
"
- + "Average pace: 0:30 min/km (0:48 min/mi)
"
- + "Average moving pace: 0:15 min/km (0:24 min/mi)
"
- + "Fastest pace: 0:10 min/km (0:16 min/mi)
"
- + "Max elevation: 550 m (1804 ft)
"
- + "Min elevation: -500 m (-1640 ft)
"
- + "Elevation gain: 6000 m (19685 ft)
"
- + "Elevation loss: 6000 m (19685 ft)
"
- + "Recorded: " + StringUtils.formatDateTime(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "
";
+ + "Moving time: 05:00
"
+ + "Average speed: 120.00 km/h (74.6 mi/h)
"
+ + "Average moving speed: 240.00 km/h (149.1 mi/h)
"
+ + "Max speed: 360.00 km/h (223.7 mi/h)
"
+ + "Average pace: 0:30 min/km (0:48 min/mi)
"
+ + "Average moving pace: 0:15 min/km (0:24 min/mi)
"
+ + "Fastest pace: 0:10 min/km (0:16 min/mi)
"
+ + "Max elevation: 550 m (1804 ft)
"
+ + "Min elevation: -500 m (-1640 ft)
"
+ + "Elevation gain: 6000 m (19685 ft)
"
+ + "Elevation loss: 6000 m (19685 ft)
"
+ + "Recorded: " + StringUtils.formatDateTime(OffsetDateTime.ofInstant(START_TIME, ZoneId.systemDefault())) + "
";
assertEquals(expected, descriptionGenerator.generateTrackDescription(track, true));
}
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 4562ad8bd..470c29c6f 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -328,7 +328,7 @@ limitations under the License.
@@ -336,7 +336,7 @@ 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 64a235bd7..21d1d721c 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java
@@ -63,6 +63,7 @@ import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.settings.SettingsActivity;
+import de.dennisguse.opentracks.share.ShareUtils;
import de.dennisguse.opentracks.ui.aggregatedStatistics.AggregatedStatisticsActivity;
import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragment;
import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
@@ -449,7 +450,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
}
if (itemId == R.id.list_context_menu_share) {
- Intent intent = IntentUtils.newShareFileIntent(this, trackIds);
+ Intent intent = ShareUtils.newShareFileIntent(this, trackIds);
intent = Intent.createChooser(intent, null);
startActivity(intent);
return true;
diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
index 6f2063a32..79add8a67 100644
--- a/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/TrackRecordedActivity.java
@@ -45,6 +45,7 @@ import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.settings.SettingsActivity;
+import de.dennisguse.opentracks.share.ShareUtils;
import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragment;
import de.dennisguse.opentracks.ui.intervals.IntervalsFragment;
import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
@@ -182,7 +183,7 @@ public class TrackRecordedActivity extends AbstractTrackDeleteActivity implement
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.track_detail_share) {
- Intent intent = Intent.createChooser(IntentUtils.newShareFileIntent(this, trackId), null);
+ Intent intent = Intent.createChooser(ShareUtils.newShareFileIntent(this, trackId), null);
startActivity(intent);
return true;
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/DescriptionGenerator.java b/src/main/java/de/dennisguse/opentracks/share/DescriptionGenerator.java
similarity index 98%
rename from src/main/java/de/dennisguse/opentracks/content/DescriptionGenerator.java
rename to src/main/java/de/dennisguse/opentracks/share/DescriptionGenerator.java
index a65f2bb26..5f16f396b 100644
--- a/src/main/java/de/dennisguse/opentracks/content/DescriptionGenerator.java
+++ b/src/main/java/de/dennisguse/opentracks/share/DescriptionGenerator.java
@@ -14,7 +14,7 @@
* the License.
*/
-package de.dennisguse.opentracks.content;
+package de.dennisguse.opentracks.share;
import android.content.Context;
import android.util.Pair;
@@ -54,8 +54,8 @@ public class DescriptionGenerator {
/**
* Generates a track description.
*
- * @param track the track
- * @param html true to output html, false to output plain text
+ * @param track the track
+ * @param html true to output html, false to output plain text
*/
public String generateTrackDescription(Track track, boolean html) {
String paragraphSeparator = html ? HTML_PARAGRAPH_SEPARATOR : TEXT_PARAGRAPH_SEPARATOR;
diff --git a/src/main/java/de/dennisguse/opentracks/share/ShareUtils.java b/src/main/java/de/dennisguse/opentracks/share/ShareUtils.java
new file mode 100644
index 000000000..97729262c
--- /dev/null
+++ b/src/main/java/de/dennisguse/opentracks/share/ShareUtils.java
@@ -0,0 +1,124 @@
+package de.dennisguse.opentracks.share;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import de.dennisguse.opentracks.R;
+import de.dennisguse.opentracks.data.ContentProviderUtils;
+import de.dennisguse.opentracks.data.ShareContentProvider;
+import de.dennisguse.opentracks.data.models.Marker;
+import de.dennisguse.opentracks.data.models.Track;
+import de.dennisguse.opentracks.io.file.TrackFileFormat;
+import de.dennisguse.opentracks.settings.PreferencesUtils;
+import de.dennisguse.opentracks.util.FileUtils;
+
+public class ShareUtils {
+
+ private static final String TAG = ShareUtils.class.getSimpleName();
+
+ private ShareUtils() {
+ }
+
+
+ /**
+ * Creates an intent to share a track file with an app.
+ *
+ * @param context the context
+ * @param trackIds the track ids
+ */
+ public static Intent newShareFileIntent(Context context, Track.Id... trackIds) {
+ if (trackIds.length == 0) {
+ throw new RuntimeException("Need to share at least one track.");
+ }
+
+ ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
+
+ String trackDescription = "";
+ if (trackIds.length == 1) {
+ Track track = contentProviderUtils.getTrack(trackIds[0]);
+ trackDescription = track == null ? "" : new DescriptionGenerator(context).generateTrackDescription(track, false);
+ }
+
+ ArrayList uris = new ArrayList<>();
+ for (Track.Id trackId : trackIds) {
+ Track track = contentProviderUtils.getTrack(trackId);
+ if (track == null) {
+ Log.e(TAG, "TrackId " + trackId.getId() + " could not be resolved.");
+ continue;
+ }
+
+ String trackName = FileUtils.sanitizeFileName(track.getName());
+ Pair uriTrackFile = ShareContentProvider.createURI(trackId, trackName, PreferencesUtils.getExportTrackFileFormat());
+ Pair uriSharePicture = ShareContentProvider.createURI(trackId, trackName, TrackFileFormat.SHARE_PICTURE_PNG);
+
+ uris.addAll(Arrays.asList(uriSharePicture.first, uriTrackFile.first));
+ }
+
+ return new Intent(Intent.ACTION_SEND_MULTIPLE)
+ .setType("image/*")
+ .putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ .putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share_track_subject))
+ .putExtra(Intent.EXTRA_TEXT, context.getString(R.string.share_track_share_file_body, trackDescription));
+ }
+
+ /**
+ * Creates an intent to share a track file with an app.
+ *
+ * @param context the context
+ * @param markerIds the marker ids
+ * @return an Intent or null (if nothing can be shared).
+ */
+ @Nullable
+ public static Intent newShareFileIntent(Context context, Marker.Id... markerIds) {
+ if (markerIds.length == 0) {
+ throw new RuntimeException("Need to share at least one marker.");
+ }
+
+ String mime = null;
+
+ ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
+ ArrayList uris = new ArrayList<>();
+ for (Marker.Id markerId : markerIds) {
+ Marker marker = contentProviderUtils.getMarker(markerId);
+ if (marker == null) {
+ Log.e(TAG, "MarkerId " + markerId.getId() + " could not be resolved.");
+ continue;
+ }
+ if (marker.getPhotoURI() == null) {
+ Log.e(TAG, "MarkerId " + markerId.getId() + " has no picture.");
+ continue;
+ }
+
+ mime = context.getContentResolver().getType(marker.getPhotoURI());
+
+ uris.add(marker.getPhotoURI());
+ }
+
+ if (uris.isEmpty()) {
+ return null;
+ }
+
+ /*
+ * Because the #166 bug, when you import KMZ tracks then it creates file:/// from markers with photo.
+ * The photos should be content:/// not file:/// because getType(uri) always returns null for file:///
+ * In .setType, to avoid side effects because the #166 bug described above it checks if mime is null.
+ * If it is then it hardcode "images/*".
+ */
+ return new Intent(Intent.ACTION_SEND_MULTIPLE)
+ .setType(mime != null ? mime : "image/*")
+ .putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ .putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share_image_subject))
+ .putExtra(Intent.EXTRA_TEXT, context.getString(R.string.share_image_body));
+ }
+
+}
diff --git a/src/main/java/de/dennisguse/opentracks/ShowOnMapProxyActivity.java b/src/main/java/de/dennisguse/opentracks/share/ShowOnMapProxyActivity.java
similarity index 96%
rename from src/main/java/de/dennisguse/opentracks/ShowOnMapProxyActivity.java
rename to src/main/java/de/dennisguse/opentracks/share/ShowOnMapProxyActivity.java
index c68bf91a5..efd33d93a 100644
--- a/src/main/java/de/dennisguse/opentracks/ShowOnMapProxyActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/share/ShowOnMapProxyActivity.java
@@ -1,4 +1,4 @@
-package de.dennisguse.opentracks;
+package de.dennisguse.opentracks.share;
import android.content.Context;
import android.content.Intent;
@@ -10,6 +10,7 @@ import androidx.appcompat.app.AppCompatActivity;
import java.util.Set;
+import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.ShareContentProvider;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
diff --git a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailFragment.java b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailFragment.java
index 229938775..66d99cfed 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerDetailFragment.java
@@ -40,6 +40,7 @@ import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.Marker;
import de.dennisguse.opentracks.databinding.MarkerDetailFragmentBinding;
+import de.dennisguse.opentracks.share.ShareUtils;
import de.dennisguse.opentracks.util.IntentUtils;
import de.dennisguse.opentracks.util.ListItemUtils;
import de.dennisguse.opentracks.util.StringUtils;
@@ -205,7 +206,7 @@ public class MarkerDetailFragment extends Fragment {
if (item.getItemId() == R.id.marker_detail_share) {
if (marker.hasPhoto()) {
- Intent intent = IntentUtils.newShareFileIntent(getContext(), marker.getId());
+ Intent intent = ShareUtils.newShareFileIntent(getContext(), marker.getId());
intent = Intent.createChooser(intent, null);
startActivity(intent);
}
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 a25b48bd1..9bc131321 100644
--- a/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/ui/markers/MarkerListActivity.java
@@ -40,6 +40,7 @@ import de.dennisguse.opentracks.data.tables.MarkerColumns;
import de.dennisguse.opentracks.databinding.MarkerListBinding;
import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
+import de.dennisguse.opentracks.share.ShareUtils;
import de.dennisguse.opentracks.ui.markers.DeleteMarkerDialogFragment.DeleteMarkerCaller;
import de.dennisguse.opentracks.ui.util.ScrollVisibleViews;
import de.dennisguse.opentracks.util.ActivityUtils;
@@ -206,7 +207,7 @@ public class MarkerListActivity extends AbstractActivity implements DeleteMarker
}
if (itemId == R.id.list_context_menu_share) {
- Intent intent = IntentUtils.newShareFileIntent(this, markerIds);
+ Intent intent = ShareUtils.newShareFileIntent(this, markerIds);
if (intent != null) {
intent = Intent.createChooser(intent, null);
startActivity(intent);
diff --git a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java
index 541dbaf39..d9c326e24 100644
--- a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java
@@ -24,24 +24,15 @@ import android.provider.MediaStore;
import android.util.Log;
import android.util.Pair;
-import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.documentfile.provider.DocumentFile;
import java.io.File;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
-import de.dennisguse.opentracks.R;
-import de.dennisguse.opentracks.content.DescriptionGenerator;
-import de.dennisguse.opentracks.data.ContentProviderUtils;
-import de.dennisguse.opentracks.data.ShareContentProvider;
import de.dennisguse.opentracks.data.models.Marker;
import de.dennisguse.opentracks.data.models.Track;
-import de.dennisguse.opentracks.io.file.TrackFileFormat;
-import de.dennisguse.opentracks.settings.PreferencesUtils;
/**
* Utilities for creating intents.
@@ -67,99 +58,6 @@ public class IntentUtils {
return new Intent(context, cls).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
}
- /**
- * Creates an intent to share a track file with an app.
- *
- * @param context the context
- * @param trackIds the track ids
- */
- public static Intent newShareFileIntent(Context context, Track.Id... trackIds) {
- if (trackIds.length == 0) {
- throw new RuntimeException("Need to share at least one track.");
- }
-
- ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
-
- String trackDescription = "";
- if (trackIds.length == 1) {
- Track track = contentProviderUtils.getTrack(trackIds[0]);
- trackDescription = track == null ? "" : new DescriptionGenerator(context).generateTrackDescription(track, false);
- }
-
- ArrayList uris = new ArrayList<>();
- for (Track.Id trackId : trackIds) {
- Track track = contentProviderUtils.getTrack(trackId);
- if (track == null) {
- Log.e(TAG, "TrackId " + trackId.getId() + " could not be resolved.");
- continue;
- }
-
- String trackName = FileUtils.sanitizeFileName(track.getName());
- Pair uriTrackFile = ShareContentProvider.createURI(trackId, trackName, PreferencesUtils.getExportTrackFileFormat());
- Pair uriSharePicture = ShareContentProvider.createURI(trackId, trackName, TrackFileFormat.SHARE_PICTURE_PNG);
-
- uris.addAll(Arrays.asList(uriSharePicture.first, uriTrackFile.first));
- }
-
- return new Intent(Intent.ACTION_SEND_MULTIPLE)
- .setType("image/*")
- .putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- .putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share_track_subject))
- .putExtra(Intent.EXTRA_TEXT, context.getString(R.string.share_track_share_file_body, trackDescription));
- }
-
- /**
- * Creates an intent to share a track file with an app.
- *
- * @param context the context
- * @param markerIds the marker ids
- * @return an Intent or null (if nothing can be shared).
- */
- @Nullable
- public static Intent newShareFileIntent(Context context, Marker.Id... markerIds) {
- if (markerIds.length == 0) {
- throw new RuntimeException("Need to share at least one marker.");
- }
-
- String mime = null;
-
- ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
- ArrayList uris = new ArrayList<>();
- for (Marker.Id markerId : markerIds) {
- Marker marker = contentProviderUtils.getMarker(markerId);
- if (marker == null) {
- Log.e(TAG, "MarkerId " + markerId.getId() + " could not be resolved.");
- continue;
- }
- if (marker.getPhotoURI() == null) {
- Log.e(TAG, "MarkerId " + markerId.getId() + " has no picture.");
- continue;
- }
-
- mime = context.getContentResolver().getType(marker.getPhotoURI());
-
- uris.add(marker.getPhotoURI());
- }
-
- if (uris.isEmpty()) {
- return null;
- }
-
- /*
- * Because the #166 bug, when you import KMZ tracks then it creates file:/// from markers with photo.
- * The photos should be content:/// not file:/// because getType(uri) always returns null for file:///
- * In .setType, to avoid side effects because the #166 bug described above it checks if mime is null.
- * If it is then it hardcode "images/*".
- */
- return new Intent(Intent.ACTION_SEND_MULTIPLE)
- .setType(mime != null ? mime : "image/*")
- .putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- .putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.share_image_subject))
- .putExtra(Intent.EXTRA_TEXT, context.getString(R.string.share_image_body));
- }
-
public static void showCoordinateOnMap(Context context, Marker marker) {
showCoordinateOnMap(context, marker.getLatitude(), marker.getLongitude(), marker.getName());
}