Use trackname for sharing files.

Fixes #130.
This commit is contained in:
Dennis Guse
2020-03-13 07:36:56 +01:00
parent 256eadd49d
commit ac528f9a10
3 changed files with 60 additions and 24 deletions
@@ -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<Uri, String> shareURIandMIME = ShareContentProvider.createURI(trackIds, "TrackName", TrackFileFormat.KML_ONLY_TRACK);
Assert.assertArrayEquals(trackIds, ShareContentProvider.parseURI(shareURIandMIME.first));
}
@Test
public void testCreateURIescapeFilename() {
long[] trackIds = {1};
Pair<Uri, String> 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);
}
}
@@ -19,6 +19,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import de.dennisguse.opentracks.android.IContentResolver; import de.dennisguse.opentracks.android.IContentResolver;
import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.Track;
@@ -58,30 +59,30 @@ public class ShareContentProvider extends CustomContentProvider implements ICont
private static final String TRACKID_DELIMITER = "_"; private static final String TRACKID_DELIMITER = "_";
static { 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_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.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.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_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.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.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_AND_SENSORDATA_AND_PICTURES.getName() + "/*/*", URI_KMZ_WITH_TRACKDETAIL_SENSORDATA_AND_PICTURES);
} }
public static Pair<Uri, String> createURI(long[] trackIds, @NonNull TrackFileFormat trackFileFormat) { public static Pair<Uri, String> createURI(long[] trackIds, String trackName, @NonNull TrackFileFormat trackFileFormat) {
if (trackIds.length == 0) { if (trackIds.length == 0) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
StringBuilder builder = new StringBuilder(); StringBuilder trackIdBuilder = new StringBuilder();
for (long trackId : trackIds) { 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); String mime = getTypeMime(uri);
Log.d(TAG, "Created uri " + uri.toString() + " with MIME " + mime); 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); return new Pair<>(uri, mime);
} }
private static long[] parseURI(Uri uri) { protected static long[] parseURI(Uri uri) {
String lastPathSegment = uri.getLastPathSegment(); List<String> uriPaths = uri.getPathSegments();
if (lastPathSegment == null) { if (uriPaths == null || uriPaths.size() < 2) {
Log.d(TAG, "URI does not contain any trackIds.");
return new long[]{}; return new long[]{};
} }
String fileExtension = "." + getTrackFileFormat(uri).getExtension(); String[] uriTrackIds = uriPaths.get(2).split(TRACKID_DELIMITER);
String[] lastPathSegmentSplit = lastPathSegment.replace(fileExtension, "").split(TRACKID_DELIMITER);
long[] trackIds = new long[lastPathSegmentSplit.length]; long[] trackIds = new long[uriTrackIds.length];
for (int i = 0; i < trackIds.length; i++) { for (int i = 0; i < trackIds.length; i++) {
trackIds[i] = Long.valueOf(lastPathSegmentSplit[i]); trackIds[i] = Long.valueOf(uriTrackIds[i]);
} }
return trackIds; return trackIds;
} }
@@ -75,9 +75,12 @@ public class IntentUtils {
if (trackIds.length == 0) { if (trackIds.length == 0) {
throw new RuntimeException("Need to share at least one track."); throw new RuntimeException("Need to share at least one track.");
} }
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
String trackDescription = ""; String trackDescription = "";
if (trackIds.length == 1) { 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); trackDescription = track == null ? "" : new DescriptionGenerator(context).generateTrackDescription(track, false);
} }
@@ -86,7 +89,12 @@ public class IntentUtils {
ArrayList<Uri> uris = new ArrayList<>(); ArrayList<Uri> uris = new ArrayList<>();
for (long trackId : trackIds) { for (long trackId : trackIds) {
Pair<Uri, String> 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<Uri, String> uriAndMime = ShareContentProvider.createURI(new long[]{trackId}, track.getName(), TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES);
uris.add(uriAndMime.first); uris.add(uriAndMime.first);
mime = uriAndMime.second; mime = uriAndMime.second;
} }
@@ -128,7 +136,6 @@ public class IntentUtils {
} }
/** /**
* Send intent to show tracks on a map (needs an another app). * 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 intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(TrackPointsColumns.TRACKID, trackIds[0]); intent.putExtra(TrackPointsColumns.TRACKID, trackIds[0]);
Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, TrackFileFormat.KMZ_WITH_TRACKDETAIL); Pair<Uri, String> uriAndMime = ShareContentProvider.createURI(trackIds, "SharingTrack", TrackFileFormat.KMZ_WITH_TRACKDETAIL);
intent.setDataAndType(uriAndMime.first, uriAndMime.second); intent.setDataAndType(uriAndMime.first, uriAndMime.second);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);