Store photos in /MyTracks/pictures directory

This commit is contained in:
Jimmy Shih
2013-10-03 18:04:17 -07:00
parent b182c1cb80
commit 9c938b1260
7 changed files with 79 additions and 54 deletions
@@ -51,7 +51,6 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.v4.app.TaskStackBuilder;
@@ -216,8 +215,10 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hasCamera = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
photoUri = savedInstanceState != null ? (Uri) savedInstanceState.getParcelable(PHOTO_URI_KEY) : null;
hasPhoto = savedInstanceState != null ? savedInstanceState.getBoolean(HAS_PHOTO_KEY, false) : false;
photoUri = savedInstanceState != null ? (Uri) savedInstanceState.getParcelable(PHOTO_URI_KEY)
: null;
hasPhoto = savedInstanceState != null ? savedInstanceState.getBoolean(HAS_PHOTO_KEY, false)
: false;
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
handleIntent(getIntent());
@@ -397,9 +398,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity implements
}
File dir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
FileUtils.SDCARD_TOP_DIR);
FileUtils.getDirectoryPath(FileUtils.PICTURES_DIR, Long.toString(trackId)));
FileUtils.ensureDirectoryExists(dir);
String fileName = SimpleDateFormat.getDateTimeInstance().format(new Date());
@@ -25,6 +25,7 @@ import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.stats.TripStatisticsUpdater;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils;
@@ -461,6 +462,19 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track
locator.getLineNumber(), locator.getColumnNumber(), message);
}
/**
* Gets the photo url for a file.
*
* @param fileName the file name
*/
protected String getPhotoUrl(String fileName) {
if (importTrackId == -1L) {
return null;
}
return FileUtils.getDirectoryPath(
FileUtils.PICTURES_DIR, Long.toString(importTrackId), fileName);
}
/**
* Creates a location.
*/
@@ -16,16 +16,17 @@
package com.google.android.apps.mytracks.io.file.importer;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.exporter.KmzTrackExporter;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.PowerManager.WakeLock;
import android.util.Log;
@@ -179,14 +180,12 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
String name = file.getName();
if (name.endsWith("." + TrackFileFormat.KML.getExtension())) {
trackImporter = new KmlFileTrackImporter(context, -1L, null);
} else {
File dir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
FileUtils.SDCARD_TOP_DIR);
FileUtils.ensureDirectoryExists(dir);
dir = new File(dir, name.substring(0, name.lastIndexOf('.')));
FileUtils.ensureDirectoryExists(dir);
trackImporter = new KmzTrackImporter(context, dir.getPath());
} else {
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
Uri uri = myTracksProviderUtils.insertTrack(new Track());
long newId = Long.parseLong(uri.getLastPathSegment());
trackImporter = new KmzTrackImporter(context, newId);
}
} else {
trackImporter = new GpxFileTrackImporter(context);
@@ -27,7 +27,6 @@ import android.content.Context;
import android.location.Location;
import android.net.Uri;
import java.io.File;
import java.util.ArrayList;
import org.xml.sax.Attributes;
@@ -65,7 +64,6 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
private static final String ATTRIBUTE_NAME = "name";
private final String photoPath;
private boolean trackStarted = false;
private String sensorName;
private ArrayList<Location> locationList;
@@ -79,15 +77,14 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
* @param context the context
* @param importTrackId track id to import to. -1L to import to a new track.
*/
public KmlFileTrackImporter(Context context, long importTrackId, String photoPath) {
this(context, importTrackId, photoPath, MyTracksProviderUtils.Factory.get(context));
public KmlFileTrackImporter(Context context, long importTrackId) {
this(context, importTrackId, MyTracksProviderUtils.Factory.get(context));
}
@VisibleForTesting
public KmlFileTrackImporter(Context context, long importTrackId, String photoPath,
MyTracksProviderUtils myTracksProviderUtils) {
public KmlFileTrackImporter(
Context context, long importTrackId, MyTracksProviderUtils myTracksProviderUtils) {
super(context, importTrackId, myTracksProviderUtils);
this.photoPath = photoPath;
}
@Override
@@ -184,9 +181,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter {
if (type == null) {
return;
}
if (photoUrl != null && photoPath != null) {
if (photoUrl != null) {
Uri uri = Uri.parse(photoUrl);
photoUrl = photoPath + File.separatorChar + uri.getLastPathSegment();
photoUrl = getPhotoUrl(uri.getLastPathSegment());
}
addWaypoint(type);
}
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.file.importer;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.io.file.exporter.KmzTrackExporter;
import com.google.android.apps.mytracks.util.FileUtils;
import android.content.Context;
import android.util.Log;
@@ -42,17 +43,24 @@ public class KmzTrackImporter implements TrackImporter {
private static final int BUFFER_SIZE = 4096;
private final Context context;
private final String photoPath;
private final long importTrackId;
public KmzTrackImporter(Context context, String photoPath) {
/**
* Constructor.
*
* @param context the context
* @param importTrackId track id to import to. This should not be -1L so that
* images in the kmz file can be imported.
*/
public KmzTrackImporter(Context context, long importTrackId) {
this.context = context;
this.photoPath = photoPath;
this.importTrackId = importTrackId;
}
@Override
public long importFile(InputStream inputStream) {
ZipInputStream zipInputStream = null;
long importedTrackId = -1L;
long trackId = importTrackId;
try {
ZipEntry zipEntry;
@@ -60,15 +68,15 @@ public class KmzTrackImporter implements TrackImporter {
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (Thread.interrupted()) {
Log.d(TAG, "Thread interrupted");
cleanImport(importedTrackId);
cleanImport(trackId);
return -1L;
}
String fileName = zipEntry.getName();
if (fileName.equals(KmzTrackExporter.KMZ_KML_FILE)) {
importedTrackId = parseKml(zipInputStream);
if (importedTrackId == -1L) {
trackId = parseKml(zipInputStream);
if (trackId == -1L) {
Log.d(TAG, "Unable to parse kml in kmz");
cleanImport(importedTrackId);
cleanImport(trackId);
return -1L;
}
} else {
@@ -79,10 +87,10 @@ public class KmzTrackImporter implements TrackImporter {
}
zipInputStream.closeEntry();
}
return importedTrackId;
return trackId;
} catch (IOException e) {
Log.e(TAG, "Unable to import file", e);
cleanImport(importedTrackId);
cleanImport(trackId);
return -1L;
} finally {
if (zipInputStream != null) {
@@ -98,15 +106,17 @@ public class KmzTrackImporter implements TrackImporter {
/**
* Cleans up import.
*
* @param importedTrackId the imported track id
* @param trackId the trackId
*/
private void cleanImport(long importedTrackId) {
if (importedTrackId != -1L) {
private void cleanImport(long trackId) {
if (trackId != -1L) {
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
myTracksProviderUtils.deleteTrack(importedTrackId);
myTracksProviderUtils.deleteTrack(trackId);
}
if (photoPath != null) {
File dir = new File(photoPath);
if (importTrackId != -1L) {
File dir = new File(
FileUtils.getDirectoryPath(FileUtils.PICTURES_DIR, Long.toString(importTrackId)));
if (dir.exists() && dir.isDirectory()) {
for (File file : dir.listFiles()) {
file.delete();
@@ -125,7 +135,7 @@ public class KmzTrackImporter implements TrackImporter {
private long parseKml(ZipInputStream zipInputStream) throws IOException {
ByteArrayInputStream byteArrayInputStream = null;
try {
KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(context, -1L, photoPath);
KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(context, importTrackId);
byteArrayInputStream = new ByteArrayInputStream(getKml(zipInputStream));
return kmlFileTrackImporter.importFile(byteArrayInputStream);
} finally {
@@ -166,7 +176,14 @@ public class KmzTrackImporter implements TrackImporter {
private void readImageFile(ZipInputStream zipInputStream, String fileName) throws IOException {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(photoPath + File.separatorChar + fileName);
if (importTrackId == -1L) {
return;
}
File dir = new File(
FileUtils.getDirectoryPath(FileUtils.PICTURES_DIR, Long.toString(importTrackId)));
FileUtils.ensureDirectoryExists(dir);
fileOutputStream = new FileOutputStream(new File(dir, fileName));
byte[] buffer = new byte[BUFFER_SIZE];
int count;
while ((count = zipInputStream.read(buffer)) != -1) {
@@ -30,14 +30,16 @@ public class FileUtils {
private FileUtils() {}
public static final String BACKUPS_DIR = "backups";
/**
* Name of the top-level directory inside the SD card where our files will be
* read from/written to.
*/
public static final String SDCARD_TOP_DIR = "MyTracks";
protected static final String SDCARD_TOP_DIR = "MyTracks";
public static final String BACKUPS_DIR = "backups";
public static final String PICTURES_DIR = "pictures";
/**
* The maximum FAT32 path length. See the FAT32 spec at
* http://msdn.microsoft.com/en-us/windows/hardware/gg463080
@@ -20,7 +20,6 @@ import static com.google.android.testing.mocking.AndroidMock.eq;
import static com.google.android.testing.mocking.AndroidMock.expect;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.io.file.importer.KmlFileTrackImporter;
import com.google.android.testing.mocking.AndroidMock;
import android.location.Location;
@@ -73,8 +72,7 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter {
Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime());
Location location1 = createLocation(1, DATE_FORMAT_1.parse(TRACK_TIME_1).getTime());
expect(myTracksProviderUtils.insertTrack((Track) AndroidMock.anyObject()))
.andReturn(TRACK_ID_0_URI);
myTracksProviderUtils.clearTrack(TRACK_ID_0);
expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0);
// A flush happens at the end
@@ -87,7 +85,7 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter {
InputStream inputStream = new ByteArrayInputStream(VALID_ONE_TRACK_ONE_SEGMENT_GPX.getBytes());
KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(
getContext(), -1L, null, myTracksProviderUtils);
getContext(), TRACK_ID_0, myTracksProviderUtils);
long trackId = kmlFileTrackImporter.importFile(inputStream);
assertEquals(TRACK_ID_0, trackId);
@@ -106,8 +104,7 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter {
Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime());
expect(myTracksProviderUtils.insertTrack((Track) AndroidMock.anyObject()))
.andReturn(TRACK_ID_0_URI);
myTracksProviderUtils.clearTrack(TRACK_ID_0);
expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0);
// A flush happens at the end
@@ -120,7 +117,7 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter {
InputStream inputStream = new ByteArrayInputStream(VALID_ONE_TRACK_TWO_SEGMENTS_GPX.getBytes());
KmlFileTrackImporter kmlFileTrackImporter = new KmlFileTrackImporter(
getContext(), -1L, null, myTracksProviderUtils);
getContext(), TRACK_ID_0, myTracksProviderUtils);
long trackId = kmlFileTrackImporter.importFile(inputStream);
assertEquals(TRACK_ID_0, trackId);