From ac528f9a10bb88439ce74ff2ce44e32f281ef730 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Fri, 13 Mar 2020 07:36:56 +0100 Subject: [PATCH] Use trackname for sharing files. Fixes #130. --- .../provider/ShareContentProviderTest.java | 28 +++++++++++++ .../provider/ShareContentProvider.java | 41 ++++++++++--------- .../opentracks/util/IntentUtils.java | 15 +++++-- 3 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 src/androidTest/java/de/dennisguse/opentracks/content/provider/ShareContentProviderTest.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/provider/ShareContentProviderTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/provider/ShareContentProviderTest.java new file mode 100644 index 000000000..7aa87ef47 --- /dev/null +++ b/src/androidTest/java/de/dennisguse/opentracks/content/provider/ShareContentProviderTest.java @@ -0,0 +1,28 @@ +package de.dennisguse.opentracks.content.provider; + +import android.net.Uri; +import android.util.Pair; + +import org.junit.Assert; +import org.junit.Test; + +import de.dennisguse.opentracks.io.file.TrackFileFormat; + +public class ShareContentProviderTest { + + @Test + public void testCreateandParseURI() { + long[] trackIds = {1, 3, 5}; + Pair shareURIandMIME = ShareContentProvider.createURI(trackIds, "TrackName", TrackFileFormat.KML_ONLY_TRACK); + + Assert.assertArrayEquals(trackIds, ShareContentProvider.parseURI(shareURIandMIME.first)); + } + + @Test + public void testCreateURIescapeFilename() { + long[] trackIds = {1}; + Pair shareURIandMIME = ShareContentProvider.createURI(trackIds, "../../&1=1", TrackFileFormat.KML_ONLY_TRACK); + + Assert.assertEquals(Uri.parse("content://de.dennisguse.opentracks.debug.content/tracks/kml_only_track/1/..%2F..%2F%261%3D1.kml"), shareURIandMIME.first); + } +} \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/ShareContentProvider.java b/src/main/java/de/dennisguse/opentracks/content/provider/ShareContentProvider.java index 34fc66f4b..0d9ac6c24 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/ShareContentProvider.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/ShareContentProvider.java @@ -19,6 +19,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; +import java.util.List; import de.dennisguse.opentracks.android.IContentResolver; import de.dennisguse.opentracks.content.data.Track; @@ -58,30 +59,30 @@ public class ShareContentProvider extends CustomContentProvider implements ICont private static final String TRACKID_DELIMITER = "_"; static { - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.GPX.getName() + "/*", URI_GPX); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.GPX.getName() + "/*/*", URI_GPX); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_ONLY_TRACK.getName() + "/*", URI_KML_ONLY); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_WITH_TRACKDETAIL.getName() + "/*", URI_KML_WITH_TRACKDETAIL); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getName() + "/*", URI_KML_WITH_TRACKDETAIL_SENSORDATA); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_ONLY_TRACK.getName() + "/*", URI_KMZ_ONLY_TRACK); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_ONLY_TRACK.getName() + "/*/*", URI_KML_ONLY); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_WITH_TRACKDETAIL.getName() + "/*/*", URI_KML_WITH_TRACKDETAIL); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KML_WITH_TRACKDETAIL_AND_SENSORDATA.getName() + "/*/*", URI_KML_WITH_TRACKDETAIL_SENSORDATA); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_ONLY_TRACK.getName() + "/*/*", URI_KMZ_ONLY_TRACK); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL.getName() + "/*", URI_KMZ_WITH_TRACKDETAIL); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA.getName() + "/*", URI_KMZ_WITH_TRACKDETAIL_AND_SENSORDATA); - uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getName() + "/*", URI_KMZ_WITH_TRACKDETAIL_SENSORDATA_AND_PICTURES); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL.getName() + "/*/*", URI_KMZ_WITH_TRACKDETAIL); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA.getName() + "/*/*", URI_KMZ_WITH_TRACKDETAIL_AND_SENSORDATA); + uriMatcher.addURI(ContentProviderUtils.AUTHORITY_PACKAGE, TracksColumns.TABLE_NAME + "/" + TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES.getName() + "/*/*", URI_KMZ_WITH_TRACKDETAIL_SENSORDATA_AND_PICTURES); } - public static Pair createURI(long[] trackIds, @NonNull TrackFileFormat trackFileFormat) { + public static Pair createURI(long[] trackIds, String trackName, @NonNull TrackFileFormat trackFileFormat) { if (trackIds.length == 0) { throw new UnsupportedOperationException(); } - StringBuilder builder = new StringBuilder(); + StringBuilder trackIdBuilder = new StringBuilder(); for (long trackId : trackIds) { - builder.append(trackId).append(TRACKID_DELIMITER); + trackIdBuilder.append(trackId).append(TRACKID_DELIMITER); } - builder.deleteCharAt(builder.lastIndexOf(TRACKID_DELIMITER)); + trackIdBuilder.deleteCharAt(trackIdBuilder.lastIndexOf(TRACKID_DELIMITER)); - Uri uri = Uri.parse(TracksColumns.CONTENT_URI + "/" + trackFileFormat.getName() + "/" + builder + "." + trackFileFormat.getExtension()); + Uri uri = Uri.parse(TracksColumns.CONTENT_URI + "/" + trackFileFormat.getName() + "/" + trackIdBuilder + "/" + Uri.encode(trackName) + "." + trackFileFormat.getExtension()); String mime = getTypeMime(uri); Log.d(TAG, "Created uri " + uri.toString() + " with MIME " + mime); @@ -89,18 +90,18 @@ public class ShareContentProvider extends CustomContentProvider implements ICont return new Pair<>(uri, mime); } - private static long[] parseURI(Uri uri) { - String lastPathSegment = uri.getLastPathSegment(); - if (lastPathSegment == null) { + protected static long[] parseURI(Uri uri) { + List uriPaths = uri.getPathSegments(); + if (uriPaths == null || uriPaths.size() < 2) { + Log.d(TAG, "URI does not contain any trackIds."); return new long[]{}; } - String fileExtension = "." + getTrackFileFormat(uri).getExtension(); - String[] lastPathSegmentSplit = lastPathSegment.replace(fileExtension, "").split(TRACKID_DELIMITER); + String[] uriTrackIds = uriPaths.get(2).split(TRACKID_DELIMITER); - long[] trackIds = new long[lastPathSegmentSplit.length]; + long[] trackIds = new long[uriTrackIds.length]; for (int i = 0; i < trackIds.length; i++) { - trackIds[i] = Long.valueOf(lastPathSegmentSplit[i]); + trackIds[i] = Long.valueOf(uriTrackIds[i]); } return trackIds; } diff --git a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java index d1d1eb673..7bb675c86 100644 --- a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java @@ -75,9 +75,12 @@ public class IntentUtils { 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 = new ContentProviderUtils(context).getTrack(trackIds[0]); + Track track = contentProviderUtils.getTrack(trackIds[0]); trackDescription = track == null ? "" : new DescriptionGenerator(context).generateTrackDescription(track, false); } @@ -86,7 +89,12 @@ public class IntentUtils { ArrayList uris = new ArrayList<>(); for (long trackId : trackIds) { - Pair uriAndMime = ShareContentProvider.createURI(new long[]{trackId}, TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES); + Track track = contentProviderUtils.getTrack(trackId); + if (track == null) { + Log.e(TAG, "TrackId " + trackId + " could not be resolved."); + } + + Pair uriAndMime = ShareContentProvider.createURI(new long[]{trackId}, track.getName(), TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES); uris.add(uriAndMime.first); mime = uriAndMime.second; } @@ -128,7 +136,6 @@ public class IntentUtils { } - /** * Send intent to show tracks on a map (needs an another app). * @@ -147,7 +154,7 @@ public class IntentUtils { Intent intent = new Intent(android.content.Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(TrackPointsColumns.TRACKID, trackIds[0]); - Pair uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KMZ_WITH_TRACKDETAIL); + Pair uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", TrackFileFormat.KMZ_WITH_TRACKDETAIL); intent.setDataAndType(uriAndMime.first, uriAndMime.second); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);