forked from upstream-mirrors/OpenTracks
Images/folders are deleted when tracks/waypoints are deleted.
This fixes #189.
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
package de.dennisguse.opentracks.content.data;
|
package de.dennisguse.opentracks.content.data;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
import android.net.Uri;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
|
||||||
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
|
|
||||||
public class TestDataUtil {
|
public class TestDataUtil {
|
||||||
|
|
||||||
@@ -73,4 +79,26 @@ public class TestDataUtil {
|
|||||||
contentProviderUtils.insertTrack(track);
|
contentProviderUtils.insertTrack(track);
|
||||||
contentProviderUtils.bulkInsertTrackPoint(trackPoints, track.getId());
|
contentProviderUtils.bulkInsertTrackPoint(trackPoints, track.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Waypoint with a photo.
|
||||||
|
*
|
||||||
|
* @param context The context.
|
||||||
|
* @param trackId The track id.
|
||||||
|
* @param location The location.
|
||||||
|
* @return the Waypoint created.
|
||||||
|
*/
|
||||||
|
public static Waypoint createWaypointWithPhoto(Context context, long trackId, Location location) throws IOException {
|
||||||
|
String photoUrl = "";
|
||||||
|
try {
|
||||||
|
File dstFile = new File(FileUtils.getImageUrl(context, trackId));
|
||||||
|
dstFile.createNewFile();
|
||||||
|
Uri photoUri = FileUtils.getUriForFile(context, dstFile);
|
||||||
|
photoUrl = photoUri.toString();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw ioe;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Waypoint("Waypoint name", "Waypoint description", "Waypoint category", "", trackId, 0.0, 0, location, photoUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+139
-6
@@ -32,6 +32,8 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,6 +46,7 @@ import de.dennisguse.opentracks.content.data.TracksColumns;
|
|||||||
import de.dennisguse.opentracks.content.data.Waypoint;
|
import de.dennisguse.opentracks.content.data.Waypoint;
|
||||||
import de.dennisguse.opentracks.content.data.WaypointsColumns;
|
import de.dennisguse.opentracks.content.data.WaypointsColumns;
|
||||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||||
|
import de.dennisguse.opentracks.util.FileUtils;
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -219,6 +222,44 @@ public class CustomContentProviderUtilsTest {
|
|||||||
Assert.assertEquals(0, waypointCursor.getCount());
|
Assert.assertEquals(0, waypointCursor.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the method {@link ContentProviderUtils#deleteAllTracks(Context)}
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDeleteAllTracks_withWaypointAndPhoto() throws IOException {
|
||||||
|
// Insert track, points and waypoint with photo at first.
|
||||||
|
long trackId = System.currentTimeMillis();
|
||||||
|
Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||||
|
|
||||||
|
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||||
|
Waypoint waypoint = TestDataUtil.createWaypointWithPhoto(context, trackId, trackPoint.getLocation());
|
||||||
|
contentProviderUtils.insertWaypoint(waypoint);
|
||||||
|
|
||||||
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
|
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
|
||||||
|
Assert.assertEquals(1, tracksCursor.getCount());
|
||||||
|
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
|
||||||
|
Assert.assertEquals(10, tracksPointsCursor.getCount());
|
||||||
|
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
|
||||||
|
Assert.assertEquals(1, waypointCursor.getCount());
|
||||||
|
// Check waypoint has photo and it's in the external storage.
|
||||||
|
Assert.assertTrue(waypoint.hasPhoto());
|
||||||
|
File dir = FileUtils.getPhotoDir(context, trackId);
|
||||||
|
Assert.assertTrue(dir.isDirectory());
|
||||||
|
Assert.assertEquals(1, dir.list().length);
|
||||||
|
Assert.assertTrue(dir.exists());
|
||||||
|
// Delete all.
|
||||||
|
contentProviderUtils.deleteAllTracks(context);
|
||||||
|
// Check whether all have been deleted.
|
||||||
|
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
|
||||||
|
Assert.assertEquals(0, tracksCursor.getCount());
|
||||||
|
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
|
||||||
|
Assert.assertEquals(0, tracksPointsCursor.getCount());
|
||||||
|
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
|
||||||
|
Assert.assertEquals(0, waypointCursor.getCount());
|
||||||
|
Assert.assertFalse(dir.exists());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the method {@link ContentProviderUtils#deleteTrack(Context, long)}.
|
* Tests the method {@link ContentProviderUtils#deleteTrack(Context, long)}.
|
||||||
*/
|
*/
|
||||||
@@ -254,6 +295,56 @@ public class CustomContentProviderUtilsTest {
|
|||||||
Assert.assertEquals(0, waypointCursor.getCount());
|
Assert.assertEquals(0, waypointCursor.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the method {@link ContentProviderUtils#deleteTrack(Context, long)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDeleteTrack_withWaypointPhoto() throws IOException {
|
||||||
|
// Insert three tracks.
|
||||||
|
long trackId = System.currentTimeMillis();
|
||||||
|
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||||
|
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId + 1, 10);
|
||||||
|
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId + 2, 10);
|
||||||
|
|
||||||
|
// Insert a waypoint in tracks trackId and trackId + 1.
|
||||||
|
TrackPoint trackPoint1 = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||||
|
Waypoint waypoint1 = TestDataUtil.createWaypointWithPhoto(context, trackId, trackPoint1.getLocation());
|
||||||
|
contentProviderUtils.insertWaypoint(waypoint1);
|
||||||
|
File dir1 = FileUtils.getPhotoDir(context, trackId);
|
||||||
|
|
||||||
|
TrackPoint trackPoint2 = contentProviderUtils.getLastValidTrackPoint(trackId + 1);
|
||||||
|
Waypoint waypoint2 = TestDataUtil.createWaypointWithPhoto(context, trackId + 1, trackPoint2.getLocation());
|
||||||
|
contentProviderUtils.insertWaypoint(waypoint2);
|
||||||
|
File dir2 = FileUtils.getPhotoDir(context, trackId + 1);
|
||||||
|
|
||||||
|
// Check.
|
||||||
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
|
Cursor tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
|
||||||
|
Assert.assertEquals(3, tracksCursor.getCount());
|
||||||
|
Cursor tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
|
||||||
|
Assert.assertEquals(30, tracksPointsCursor.getCount());
|
||||||
|
Cursor waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
|
||||||
|
Assert.assertEquals(2, waypointCursor.getCount());
|
||||||
|
Assert.assertTrue(waypoint1.hasPhoto());
|
||||||
|
Assert.assertTrue(dir1.isDirectory());
|
||||||
|
Assert.assertEquals(1, dir1.list().length);
|
||||||
|
Assert.assertTrue(dir1.exists());
|
||||||
|
Assert.assertTrue(dir2.isDirectory());
|
||||||
|
Assert.assertEquals(1, dir2.list().length);
|
||||||
|
Assert.assertTrue(dir2.exists());
|
||||||
|
// Delete one track.
|
||||||
|
contentProviderUtils.deleteTrack(context, trackId);
|
||||||
|
// Check whether all data of a track has been deleted.
|
||||||
|
tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, TracksColumns._ID);
|
||||||
|
Assert.assertEquals(2, tracksCursor.getCount());
|
||||||
|
tracksPointsCursor = contentResolver.query(TrackPointsColumns.CONTENT_URI_BY_ID, null, null, null, TrackPointsColumns._ID);
|
||||||
|
Assert.assertEquals(20, tracksPointsCursor.getCount());
|
||||||
|
waypointCursor = contentResolver.query(WaypointsColumns.CONTENT_URI, null, null, null, WaypointsColumns._ID);
|
||||||
|
Assert.assertEquals(1, waypointCursor.getCount());
|
||||||
|
Assert.assertFalse(dir1.exists());
|
||||||
|
Assert.assertTrue(dir2.exists());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the method {@link ContentProviderUtils#getAllTracks()}
|
* Tests the method {@link ContentProviderUtils#getAllTracks()}
|
||||||
*/
|
*/
|
||||||
@@ -387,7 +478,7 @@ public class CustomContentProviderUtilsTest {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the method
|
* Tests the method
|
||||||
* {@link ContentProviderUtils#deleteWaypoint(long)}
|
* {@link ContentProviderUtils#deleteWaypoint(Context, long)}
|
||||||
* when there is only one waypoint in the track.
|
* when there is only one waypoint in the track.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@@ -401,14 +492,56 @@ public class CustomContentProviderUtilsTest {
|
|||||||
waypoint1.setTrackId(trackId);
|
waypoint1.setTrackId(trackId);
|
||||||
contentProviderUtils.insertWaypoint(waypoint1);
|
contentProviderUtils.insertWaypoint(waypoint1);
|
||||||
|
|
||||||
// Delete
|
// Check insert was done.
|
||||||
contentProviderUtils.deleteWaypoint(1);
|
Assert.assertEquals(contentProviderUtils.getWaypointCount(trackId), 1);
|
||||||
|
|
||||||
Assert.assertNull(contentProviderUtils.getWaypoint(1));
|
// Get waypoint id that needs to delete.
|
||||||
|
long waypoint1Id = ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1));
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
contentProviderUtils.deleteWaypoint(context, waypoint1Id);
|
||||||
|
|
||||||
|
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the method {@link ContentProviderUtils#deleteWaypoint(long)} when there is more than one waypoint in the track.
|
* Tests the method
|
||||||
|
* {@link ContentProviderUtils#deleteWaypoint(Context, long)}
|
||||||
|
* when there is only one waypoint in the track.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDeleteWaypoint_onlyOneWayPointWithPhotoUrl() throws IOException {
|
||||||
|
long trackId = System.currentTimeMillis();
|
||||||
|
TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10);
|
||||||
|
|
||||||
|
// Insert at first.
|
||||||
|
TrackPoint trackPoint = contentProviderUtils.getLastValidTrackPoint(trackId);
|
||||||
|
Waypoint waypoint1 = TestDataUtil.createWaypointWithPhoto(context, trackId, trackPoint.getLocation());
|
||||||
|
contentProviderUtils.insertWaypoint(waypoint1);
|
||||||
|
|
||||||
|
// Check insert was done.
|
||||||
|
Assert.assertEquals(contentProviderUtils.getWaypointCount(trackId), 1);
|
||||||
|
|
||||||
|
// Get waypoint id that needs to delete.
|
||||||
|
long waypoint1Id = ContentUris.parseId(contentProviderUtils.insertWaypoint(waypoint1));
|
||||||
|
|
||||||
|
// Check waypoint has photo and it's in the external storage.
|
||||||
|
Assert.assertTrue(waypoint1.hasPhoto());
|
||||||
|
File dir = FileUtils.getPhotoDir(context, trackId);
|
||||||
|
Assert.assertTrue(dir.isDirectory());
|
||||||
|
Assert.assertEquals(1, dir.list().length);
|
||||||
|
Assert.assertTrue(dir.exists());
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
contentProviderUtils.deleteWaypoint(context, waypoint1Id);
|
||||||
|
|
||||||
|
// Check waypoint doesn't exists and photo folder was deleted.
|
||||||
|
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
||||||
|
Assert.assertFalse(dir.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the method {@link ContentProviderUtils#deleteWaypoint(Context, long)} when there is more than one waypoint in the track.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteWaypoint_hasNextWayPoint() {
|
public void testDeleteWaypoint_hasNextWayPoint() {
|
||||||
@@ -444,7 +577,7 @@ public class CustomContentProviderUtilsTest {
|
|||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
Assert.assertNotNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
Assert.assertNotNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
||||||
contentProviderUtils.deleteWaypoint(waypoint1Id);
|
contentProviderUtils.deleteWaypoint(context, waypoint1Id);
|
||||||
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
Assert.assertNull(contentProviderUtils.getWaypoint(waypoint1Id));
|
||||||
|
|
||||||
Assert.assertEquals(MOCK_DESC, contentProviderUtils.getWaypoint(waypoint2Id).getDescription());
|
Assert.assertEquals(MOCK_DESC, contentProviderUtils.getWaypoint(waypoint2Id).getDescription());
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class ContentProviderUtils {
|
|||||||
contentResolver.delete(TracksColumns.CONTENT_URI, null, null);
|
contentResolver.delete(TracksColumns.CONTENT_URI, null, null);
|
||||||
|
|
||||||
File dir = FileUtils.getPhotoDir(context);
|
File dir = FileUtils.getPhotoDir(context);
|
||||||
deleteDirectoryRecurse(dir);
|
FileUtils.deleteDirectoryRecurse(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,6 +181,9 @@ public class ContentProviderUtils {
|
|||||||
public void deleteTrack(Context context, long trackId) {
|
public void deleteTrack(Context context, long trackId) {
|
||||||
deleteTrackPointsAndWaypoints(context, trackId);
|
deleteTrackPointsAndWaypoints(context, trackId);
|
||||||
|
|
||||||
|
// Delete track folder resources.
|
||||||
|
FileUtils.deleteDirectoryRecurse(FileUtils.getPhotoDir(context, trackId));
|
||||||
|
|
||||||
// Delete track last since it triggers a database vacuum call
|
// Delete track last since it triggers a database vacuum call
|
||||||
contentResolver.delete(TracksColumns.CONTENT_URI, TracksColumns._ID + "=?", new String[]{Long.toString(trackId)});
|
contentResolver.delete(TracksColumns.CONTENT_URI, TracksColumns._ID + "=?", new String[]{Long.toString(trackId)});
|
||||||
}
|
}
|
||||||
@@ -196,21 +199,6 @@ public class ContentProviderUtils {
|
|||||||
contentResolver.delete(TrackPointsColumns.CONTENT_URI_BY_ID, where, selectionArgs);
|
contentResolver.delete(TrackPointsColumns.CONTENT_URI_BY_ID, where, selectionArgs);
|
||||||
|
|
||||||
contentResolver.delete(WaypointsColumns.CONTENT_URI, WaypointsColumns.TRACKID + "=?", new String[]{Long.toString(trackId)});
|
contentResolver.delete(WaypointsColumns.CONTENT_URI, WaypointsColumns.TRACKID + "=?", new String[]{Long.toString(trackId)});
|
||||||
deleteDirectoryRecurse(FileUtils.getPhotoDir(context, trackId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the directory recursively.
|
|
||||||
*
|
|
||||||
* @param dir the directory
|
|
||||||
*/
|
|
||||||
private void deleteDirectoryRecurse(File dir) {
|
|
||||||
if (dir != null && dir.exists() && dir.isDirectory()) {
|
|
||||||
for (File child : dir.listFiles()) {
|
|
||||||
deleteDirectoryRecurse(child);
|
|
||||||
}
|
|
||||||
dir.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -392,11 +380,11 @@ public class ContentProviderUtils {
|
|||||||
return waypoint;
|
return waypoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteWaypoint(long waypointId) {
|
public void deleteWaypoint(Context context, long waypointId) {
|
||||||
final Waypoint waypoint = getWaypoint(waypointId);
|
final Waypoint waypoint = getWaypoint(waypointId);
|
||||||
if (waypoint != null && waypoint.hasPhoto()) {
|
if (waypoint != null && waypoint.hasPhoto()) {
|
||||||
Uri uri = waypoint.getPhotoURI();
|
Uri uri = waypoint.getPhotoURI();
|
||||||
File file = new File(uri.getPath());
|
File file = FileUtils.getPhotoFileIfExists(context, waypoint.getTrackId(), uri);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
File parent = file.getParentFile();
|
File parent = file.getParentFile();
|
||||||
file.delete();
|
file.delete();
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class DeleteMarkerDialogFragment extends DialogFragment {
|
|||||||
public void run() {
|
public void run() {
|
||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
|
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(fragmentActivity);
|
||||||
for (long markerId : markerIds) {
|
for (long markerId : markerIds) {
|
||||||
contentProviderUtils.deleteWaypoint(markerId);
|
contentProviderUtils.deleteWaypoint(getContext(), markerId);
|
||||||
}
|
}
|
||||||
caller.onDeleteMarkerDone();
|
caller.onDeleteMarkerDone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,6 @@ public class KmzTrackImporter implements TrackImporter {
|
|||||||
|
|
||||||
zipInputStream.closeEntry();
|
zipInputStream.closeEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
return trackId;
|
return trackId;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Unable to import file", e);
|
Log.e(TAG, "Unable to import file", e);
|
||||||
@@ -241,16 +240,6 @@ public class KmzTrackImporter implements TrackImporter {
|
|||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||||
contentProviderUtils.deleteTrack(context, trackId);
|
contentProviderUtils.deleteTrack(context, trackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (importTrackId != -1L) {
|
|
||||||
File dir = FileUtils.getPhotoDir(context, importTrackId);
|
|
||||||
if (dir.exists() && dir.isDirectory()) {
|
|
||||||
for (File file : dir.listFiles()) {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
dir.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -284,4 +284,20 @@ public class FileUtils {
|
|||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the directory recursively.
|
||||||
|
*
|
||||||
|
* @param file the directory
|
||||||
|
*/
|
||||||
|
public static void deleteDirectoryRecurse(File file) {
|
||||||
|
if (file != null && file.exists() && file.isDirectory()) {
|
||||||
|
for (File child : file.listFiles()) {
|
||||||
|
deleteDirectoryRecurse(child);
|
||||||
|
}
|
||||||
|
file.delete();
|
||||||
|
} else if (file != null && file.isFile()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user