forked from upstream-mirrors/OpenTracks
Fixing issue 190 (second step: refactoring mymaps uploading)
This commit is contained in:
@@ -26,6 +26,7 @@ import com.google.android.apps.mytracks.io.AuthManagerFactory;
|
||||
import com.google.android.apps.mytracks.io.GpxImporter;
|
||||
import com.google.android.apps.mytracks.io.SendToDocs;
|
||||
import com.google.android.apps.mytracks.io.SendToMyMaps;
|
||||
import com.google.android.apps.mytracks.io.SendToMyMaps.OnSendCompletedListener;
|
||||
import com.google.android.apps.mytracks.io.TrackWriter;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory;
|
||||
import com.google.android.apps.mytracks.io.TrackWriterFactory.TrackFileFormat;
|
||||
@@ -55,6 +56,8 @@ import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
@@ -523,8 +526,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
if (results.hasExtra("mapid")) {
|
||||
sendToMyMapsMapId = results.getStringExtra("mapid");
|
||||
}
|
||||
setProgressMessage(getString(
|
||||
R.string.progress_message_authenticating_mymaps));
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_mymaps);
|
||||
authenticate(results, MyTracksConstants.SEND_TO_GOOGLE,
|
||||
MyMapsConstants.MAPSHOP_SERVICE);
|
||||
} else {
|
||||
@@ -590,7 +593,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
if (resultCode == RESULT_OK) {
|
||||
setProgressValue(0);
|
||||
setProgressMessage(
|
||||
getString(R.string.progress_message_authenticating_docs));
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(results,
|
||||
MyTracksConstants.AUTHENTICATE_TO_TRIX, "writely");
|
||||
} else {
|
||||
@@ -602,7 +605,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
if (resultCode == RESULT_OK) {
|
||||
setProgressValue(30);
|
||||
setProgressMessage(
|
||||
getString(R.string.progress_message_authenticating_docs));
|
||||
R.string.progress_message_authenticating_docs);
|
||||
authenticate(results, MyTracksConstants.SEND_TO_DOCS, "wise");
|
||||
} else {
|
||||
dismissDialogSafely(DIALOG_PROGRESS);
|
||||
@@ -613,7 +616,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
Log.d(MyTracksConstants.TAG, "Sending to Docs....");
|
||||
setProgressValue(50);
|
||||
setProgressMessage(getString(R.string.progress_message_sending_docs));
|
||||
setProgressMessage(R.string.progress_message_sending_docs);
|
||||
final long trackId = results.getLongExtra("trackid", selectedTrackId);
|
||||
final SendToDocs sender = new SendToDocs(this, authMap.get("wise"),
|
||||
authMap.get("writely"), trackId);
|
||||
@@ -644,30 +647,30 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
case MyTracksConstants.SEND_TO_GOOGLE: {
|
||||
if (results != null && resultCode == RESULT_OK) {
|
||||
final String mapid;
|
||||
final String mapId;
|
||||
final long trackId;
|
||||
if (results.hasExtra("mapid")) {
|
||||
mapid = results.getStringExtra("mapid");
|
||||
mapId = results.getStringExtra("mapid");
|
||||
} else {
|
||||
mapid = "new";
|
||||
mapId = "new";
|
||||
}
|
||||
if (results.hasExtra("trackid")) {
|
||||
trackId = results.getLongExtra("trackid", -1);
|
||||
} else {
|
||||
trackId = selectedTrackId;
|
||||
}
|
||||
final SendToMyMaps sender = new SendToMyMaps(this, mapid, auth,
|
||||
trackId, this/*progressIndicator*/);
|
||||
Runnable onCompletion = new Runnable() {
|
||||
public void run() {
|
||||
sendToMyMapsMessage = sender.getStatusMessage();
|
||||
sendToMyMapsSuccess = sender.wasSuccess();
|
||||
|
||||
OnSendCompletedListener onCompletion = new OnSendCompletedListener() {
|
||||
@Override
|
||||
public void onSendCompleted(String mapId, boolean success, int statusMessage) {
|
||||
sendToMyMapsMessage = getString(statusMessage);
|
||||
sendToMyMapsSuccess = success;
|
||||
if (sendToMyMapsSuccess) {
|
||||
sendToMyMapsMapId = sender.getMapId();
|
||||
sendToMyMapsMapId = mapId;
|
||||
// Update the map id for this track:
|
||||
try {
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
track.setMapId(sender.getMapId());
|
||||
track.setMapId(mapId);
|
||||
providerUtils.updateTrack(track);
|
||||
} catch (RuntimeException e) {
|
||||
// If that fails whatever reasons we'll just log an error, but
|
||||
@@ -688,8 +691,13 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
}
|
||||
}
|
||||
};
|
||||
sender.setOnCompletion(onCompletion);
|
||||
sender.run();
|
||||
final SendToMyMaps sender = new SendToMyMaps(this, mapId, auth,
|
||||
trackId, this/*progressIndicator*/, onCompletion);
|
||||
|
||||
HandlerThread handlerThread = new HandlerThread("SendToMyMaps");
|
||||
handlerThread.start();
|
||||
Handler handler = new Handler(handlerThread.getLooper());
|
||||
handler.post(sender);
|
||||
} else {
|
||||
dismissDialogSafely(DIALOG_PROGRESS);
|
||||
}
|
||||
@@ -953,18 +961,31 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
});
|
||||
}
|
||||
|
||||
public void setProgressMessage(final String text) {
|
||||
// ProgressIndicator implementation
|
||||
|
||||
@Override
|
||||
public void setProgressMessage(int resId) {
|
||||
setProgressMessage(getString(resId));
|
||||
}
|
||||
|
||||
private void setProgressMessage(final String message) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.setMessage(text);
|
||||
progressDialog.setMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearProgressMessage() {
|
||||
setProgressMessage("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressValue(final int percent) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
@@ -1278,7 +1299,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
return;
|
||||
}
|
||||
setProgressValue(0);
|
||||
setProgressMessage("");
|
||||
clearProgressMessage();
|
||||
showDialogSafely(DIALOG_PROGRESS);
|
||||
if (sendToGoogleDialog.getSendToMyMaps()) {
|
||||
if (!sendToGoogleDialog.getCreateNewMap()) {
|
||||
@@ -1286,8 +1307,8 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
startActivityForResult(listIntent, MyTracksConstants.GET_MAP);
|
||||
} else {
|
||||
setProgressValue(0);
|
||||
setProgressMessage(getString(
|
||||
R.string.progress_message_authenticating_mymaps));
|
||||
setProgressMessage(
|
||||
R.string.progress_message_authenticating_mymaps);
|
||||
authenticate(new Intent(), MyTracksConstants.SEND_TO_GOOGLE,
|
||||
MyMapsConstants.MAPSHOP_SERVICE);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ package com.google.android.apps.mytracks;
|
||||
*/
|
||||
public interface ProgressIndicator {
|
||||
|
||||
public void setProgressMessage(String text);
|
||||
public void setProgressMessage(int resId);
|
||||
public void clearProgressMessage();
|
||||
|
||||
public void setProgressValue(int percent);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import com.google.android.apps.mytracks.MyTracksSettings;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TrackBuffer;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.stats.DoubleBuffer;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
@@ -44,53 +43,53 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
/**
|
||||
* A helper class used to transmit tracks to Google MyMaps.
|
||||
* A new instance should be used for each upload.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class SendToMyMaps {
|
||||
public class SendToMyMaps implements Runnable {
|
||||
|
||||
public static final String NEW_MAP_ID = "new";
|
||||
private static final String END_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/red-dot.png";
|
||||
private static final String START_ICON_URL =
|
||||
"http://maps.google.com/mapfiles/ms/micons/green-dot.png";
|
||||
private static final int MAX_POINTS_PER_UPLOAD = 2048;
|
||||
|
||||
private final Activity context;
|
||||
private final AuthManager auth;
|
||||
private final long trackId;
|
||||
private final ProgressIndicator progressIndicator;
|
||||
private final OnSendCompletedListener onCompletion;
|
||||
private final StringUtils stringUtils;
|
||||
private final MyTracksProviderUtils providerUtils;
|
||||
private String mapId;
|
||||
|
||||
private String statusMessage = "";
|
||||
private boolean success = true;
|
||||
private Runnable onCompletion;
|
||||
|
||||
private HandlerThread handlerThread;
|
||||
private Handler handler;
|
||||
|
||||
private String originalDescription;
|
||||
|
||||
// GData service
|
||||
private MyMapsGDataWrapper wrapper;
|
||||
private MyMapsGDataConverter gdataConverter;
|
||||
|
||||
private Location last = null;
|
||||
// Progress status
|
||||
private int totalLocationsRead;
|
||||
private int totalLocationsPrepared;
|
||||
private int totalLocationsUploaded;
|
||||
private int totalLocations;
|
||||
private int totalSegmentsUploaded;
|
||||
|
||||
private Vector<Double> distances;
|
||||
private Vector<Double> elevations;
|
||||
private DoubleBuffer elevationBuffer;
|
||||
public interface OnSendCompletedListener {
|
||||
void onSendCompleted(String mapId, boolean success, int statusMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a buffer of locations for transmission to google maps.
|
||||
@@ -100,8 +99,8 @@ public class SendToMyMaps {
|
||||
* @return an array of tracks each with a sub section of the points in the
|
||||
* original buffer
|
||||
*/
|
||||
private ArrayList<Track> prepareLocations(Track track,
|
||||
TrackBuffer buffer) {
|
||||
private ArrayList<Track> prepareLocations(
|
||||
Track track, Iterable<Location> locations) {
|
||||
ArrayList<Track> splitTracks = new ArrayList<Track>();
|
||||
|
||||
// Create segments from each full track:
|
||||
@@ -115,8 +114,10 @@ public class SendToMyMaps {
|
||||
segmentStats.setStartTime(trackStats.getStartTime());
|
||||
segmentStats.setStopTime(trackStats.getStopTime());
|
||||
boolean startNewTrackSegment = false;
|
||||
for (int i = 0; i < buffer.getLocationsLoaded(); ++i) {
|
||||
Location loc = buffer.get(i);
|
||||
for (Location loc : locations) {
|
||||
if (totalLocationsPrepared % 100 == 0) {
|
||||
updateProgress();
|
||||
}
|
||||
if (loc.getLatitude() > 90) {
|
||||
startNewTrackSegment = true;
|
||||
}
|
||||
@@ -141,6 +142,7 @@ public class SendToMyMaps {
|
||||
segmentStats.setStartTime(loc.getTime());
|
||||
}
|
||||
}
|
||||
totalLocationsPrepared++;
|
||||
}
|
||||
|
||||
prepareTrackSegment(segment, splitTracks);
|
||||
@@ -222,44 +224,19 @@ public class SendToMyMaps {
|
||||
|
||||
/**
|
||||
* Sets the current upload progress.
|
||||
*
|
||||
* @param track The track being uploaded
|
||||
* @param totalLocationsRead The total number of locations already read and
|
||||
* uploaded
|
||||
* @param segmentSize The percent of total that each segment corresponds to
|
||||
* @param progressInSegment The approximate progress in this segment
|
||||
*/
|
||||
private void setProgress(final Track track, int totalLocationsRead,
|
||||
double segmentSize, double progressInSegment) {
|
||||
long totalLocations = track.getStopId() - track.getStartId();
|
||||
|
||||
private void updateProgress() {
|
||||
// The percent of the total that represents the completed part of this
|
||||
// segment.
|
||||
double percentSegmentInTotal = (segmentSize * progressInSegment);
|
||||
|
||||
int progress = (int) ((100.0 * totalLocationsRead / totalLocations)
|
||||
+ percentSegmentInTotal);
|
||||
progress = Math.min(99, progress);
|
||||
progressIndicator.setProgressValue(progress);
|
||||
int totalPercentage =
|
||||
(totalLocationsRead + totalLocationsPrepared + totalLocationsUploaded)
|
||||
/ (totalLocations * 3);
|
||||
totalPercentage = Math.min(99, totalPercentage);
|
||||
progressIndicator.setProgressValue(totalPercentage);
|
||||
}
|
||||
|
||||
private boolean uploadAllTrackPoints(final Track track) {
|
||||
int totalLocationsRead = 0;
|
||||
// TODO: This might not actually be accurate.
|
||||
long totalLocations = track.getStopId() - track.getStartId();
|
||||
|
||||
// Limit the number of elevation readings. Ideally we would want around 250.
|
||||
int elevationSamplingFrequency =
|
||||
Math.max(1, (int) (totalLocations / 250.0));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"Using elevation sampling factor: " + elevationSamplingFrequency
|
||||
+ " on " + totalLocations);
|
||||
double totalDistance = 0;
|
||||
Location lastLocation = null;
|
||||
|
||||
TrackBuffer buffer = new TrackBuffer((int) Math.min(2048, totalLocations));
|
||||
int part = 1;
|
||||
|
||||
private boolean uploadAllTrackPoints(
|
||||
final Track track, String originalDescription) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(
|
||||
MyTracksSettings.SETTINGS_NAME, 0);
|
||||
boolean metricUnits = true;
|
||||
@@ -269,100 +246,159 @@ public class SendToMyMaps {
|
||||
true);
|
||||
}
|
||||
|
||||
// For the progress monitor:
|
||||
// For each track segment 33% = read, 33% = prep & 33% = upload
|
||||
// Note: These numbers are very rough.
|
||||
|
||||
// The size of each segment in the 100% progress
|
||||
double segmentSize = buffer.getSize() * 100.0 / totalLocations;
|
||||
while (success && buffer.getLastLocationRead() < track.getStopId()) {
|
||||
setProgress(track, totalLocationsRead, segmentSize, 0.0);
|
||||
Cursor locationsCursor =
|
||||
providerUtils.getLocationsCursor(track.getId(), 0, -1, false);
|
||||
try {
|
||||
if (!locationsCursor.moveToFirst()) {
|
||||
Log.w(MyTracksConstants.TAG, "Unable to get any points to upload");
|
||||
return false;
|
||||
}
|
||||
|
||||
totalLocationsRead = 0;
|
||||
totalLocationsPrepared = 0;
|
||||
totalLocationsUploaded = 0;
|
||||
totalLocations = locationsCursor.getCount();
|
||||
totalSegmentsUploaded = 0;
|
||||
|
||||
// Limit the number of elevation readings. Ideally we would want around 250.
|
||||
int elevationSamplingFrequency =
|
||||
Math.max(1, (int) (totalLocations / 250.0));
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"Using elevation sampling factor: " + elevationSamplingFrequency
|
||||
+ " on " + totalLocations);
|
||||
double totalDistance = 0;
|
||||
|
||||
Vector<Double> distances = new Vector<Double>();
|
||||
Vector<Double> elevations = new Vector<Double>();
|
||||
DoubleBuffer elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
List<Location> locations = new ArrayList<Location>(MAX_POINTS_PER_UPLOAD);
|
||||
progressIndicator.setProgressMessage(
|
||||
context.getString(R.string.progress_message_reading_track));
|
||||
|
||||
providerUtils.getTrackPoints(track, buffer);
|
||||
if (buffer.getLocationsLoaded() <= 0 || buffer.getSize() <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (totalLocationsRead == 0) {
|
||||
// Put a marker at the first point of the first valid segment:
|
||||
uploadMarker(track, buffer.get(0), true);
|
||||
}
|
||||
last = buffer.get(buffer.getLocationsLoaded() - 1);
|
||||
|
||||
// Extract the elevation profile.
|
||||
for (int i = 0; i < buffer.getLocationsLoaded(); i++) {
|
||||
// Add all points to the smoothing buffer.
|
||||
Location l = buffer.get(i);
|
||||
if (l != null && MyTracksUtils.isValidLocation(l)) {
|
||||
elevationBuffer.setNext(metricUnits ? l.getAltitude()
|
||||
: l.getAltitude() * UnitConversions.M_TO_FT);
|
||||
R.string.progress_message_reading_track);
|
||||
Location lastLocation = null;
|
||||
do {
|
||||
if (totalLocationsRead % 100 == 0) {
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
Location loc = providerUtils.createLocation(locationsCursor);
|
||||
locations.add(loc);
|
||||
|
||||
if (totalLocationsRead == 0) {
|
||||
// Put a marker at the first point of the first valid segment:
|
||||
uploadMarker(track, loc, true);
|
||||
}
|
||||
|
||||
// Add to the elevation profile.
|
||||
if (loc != null && MyTracksUtils.isValidLocation(loc)) {
|
||||
// All points go into the smoothing buffer...
|
||||
elevationBuffer.setNext(metricUnits ? loc.getAltitude()
|
||||
: loc.getAltitude() * UnitConversions.M_TO_FT);
|
||||
if (lastLocation != null) {
|
||||
double dist = lastLocation.distanceTo(l);
|
||||
double dist = lastLocation.distanceTo(loc);
|
||||
totalDistance += dist;
|
||||
}
|
||||
lastLocation = l;
|
||||
|
||||
// Only add some data points to keep the url short.
|
||||
if (i % elevationSamplingFrequency == 0) {
|
||||
|
||||
// ...but only a few points are really used to keep the url short.
|
||||
if (totalLocationsRead % elevationSamplingFrequency == 0) {
|
||||
distances.add(totalDistance);
|
||||
elevations.add(elevationBuffer.getAverage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setProgress(track, totalLocationsRead, segmentSize, 0.3333);
|
||||
progressIndicator.setProgressMessage(
|
||||
context.getString(R.string.progress_message_preparing_track));
|
||||
|
||||
ArrayList<Track> splitTracks = prepareLocations(track, buffer);
|
||||
|
||||
int i = 0;
|
||||
for (Track t : splitTracks) {
|
||||
if (part > 1) {
|
||||
t.setName(t.getName() + " "
|
||||
+ String.format(context.getString(R.string.part), part));
|
||||
|
||||
// If the location was not valid, it's a segment split, so make sure the
|
||||
// distance between the previous segment and the new one is not accounted
|
||||
// for in the next iteration.
|
||||
lastLocation = loc;
|
||||
|
||||
// Every now and then, upload the accumulated points
|
||||
if (totalLocationsRead % MAX_POINTS_PER_UPLOAD
|
||||
== MAX_POINTS_PER_UPLOAD - 1) {
|
||||
if (!prepareAndUploadPoints(track, locations)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
part++;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Prepared feature for upload w/ "
|
||||
+ t.getLocations().size() + " points.");
|
||||
|
||||
//
|
||||
// Transmit tracks via GData feed:
|
||||
// -------------------------------
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Uploading to map " + mapId + " w/ auth " + auth);
|
||||
if (!uploadTrackPoints(track, t,
|
||||
totalLocationsRead, segmentSize)) {
|
||||
success = false;
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
|
||||
totalLocationsRead++;
|
||||
} while (locationsCursor.moveToNext());
|
||||
|
||||
// Do a final upload with what's left
|
||||
if (!prepareAndUploadPoints(track, locations)) {
|
||||
return false;
|
||||
}
|
||||
totalLocationsRead += buffer.getLocationsLoaded();
|
||||
|
||||
// Put an end marker at the last point of the last valid segment:
|
||||
if (lastLocation != null) {
|
||||
track.setDescription("<p>" + originalDescription + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(
|
||||
track, distances, elevations)
|
||||
+ "</p>");
|
||||
return uploadMarker(track, lastLocation, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
locationsCursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean prepareAndUploadPoints(Track track, List<Location> locations) {
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_preparing_track);
|
||||
updateProgress();
|
||||
|
||||
int numLocations = locations.size();
|
||||
if (numLocations < 2) {
|
||||
Log.d(MyTracksConstants.TAG, "Not preparing/uploading too few points");
|
||||
totalLocationsUploaded += numLocations;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prepare/pre-process the points
|
||||
ArrayList<Track> splitTracks = prepareLocations(track, locations);
|
||||
|
||||
// Start uploading them
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_sending_mymaps);
|
||||
for (Track splitTrack : splitTracks) {
|
||||
if (totalSegmentsUploaded > 1) {
|
||||
splitTrack.setName(splitTrack.getName() + " "
|
||||
+ String.format(
|
||||
context.getString(R.string.part), totalSegmentsUploaded));
|
||||
}
|
||||
totalSegmentsUploaded++;
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Prepared feature for upload w/ "
|
||||
+ splitTrack.getLocations().size() + " points.");
|
||||
|
||||
// Transmit tracks via GData feed:
|
||||
// -------------------------------
|
||||
Log.d(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: Uploading to map " + mapId + " w/ auth " + auth);
|
||||
if (!uploadTrackPoints(splitTrack)) {
|
||||
Log.e(MyTracksConstants.TAG, "Uploading failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
locations.clear();
|
||||
totalLocationsUploaded += numLocations;
|
||||
updateProgress();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a given list of tracks to Google MyMaps using the maps GData feed.
|
||||
*
|
||||
* @param track the track meta-data is used for the map name
|
||||
*/
|
||||
private boolean uploadTrackPoints(final Track track, final Track currentTrack,
|
||||
int totalLocationsRead, double segmentSize) {
|
||||
setProgress(track, totalLocationsRead, segmentSize, 0.6666);
|
||||
progressIndicator.setProgressMessage(
|
||||
context.getString(R.string.progress_message_sending_mymaps));
|
||||
private boolean uploadTrackPoints(final Track track) {
|
||||
return wrapper.runQuery(new QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client)
|
||||
throws AuthenticationException, IOException, Exception {
|
||||
String featureFeed = MapsClient.getFeaturesFeed(mapId);
|
||||
Log.d(MyTracksConstants.TAG, "Feature feed url: " + featureFeed);
|
||||
uploadTrackPoints(track, currentTrack, client, featureFeed);
|
||||
uploadTrackPoints(track, client, featureFeed);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -373,9 +409,9 @@ public class SendToMyMaps {
|
||||
* @param track The track that will be uploaded to this map
|
||||
* @return True on success.
|
||||
*/
|
||||
private boolean createNewMap(final Track track) {
|
||||
progressIndicator.setProgressMessage(context
|
||||
.getString(R.string.progress_message_creating_map));
|
||||
private boolean createNewMap(final Track track, final String description) {
|
||||
progressIndicator.setProgressMessage(
|
||||
R.string.progress_message_creating_map);
|
||||
return wrapper.runQuery(new QueryFunction() {
|
||||
@Override
|
||||
public void query(MapsClient client) throws IOException, Exception {
|
||||
@@ -384,7 +420,7 @@ public class SendToMyMaps {
|
||||
Log.d(MyTracksConstants.TAG, "Map feed is " + mapFeed);
|
||||
MyMapsMapMetadata metaData = new MyMapsMapMetadata();
|
||||
metaData.setTitle(track.getName());
|
||||
metaData.setDescription(originalDescription + " - "
|
||||
metaData.setDescription(description + " - "
|
||||
+ track.getCategory() + " - "
|
||||
+ context.getString(R.string.new_map_description));
|
||||
SharedPreferences preferences = context.getSharedPreferences(
|
||||
@@ -404,15 +440,15 @@ public class SendToMyMaps {
|
||||
});
|
||||
}
|
||||
|
||||
private boolean uploadTrackPoints(final Track track,
|
||||
Track splitTrack,
|
||||
private boolean uploadTrackPoints(Track splitTrack,
|
||||
MapsClient client,
|
||||
String featureFeed)
|
||||
throws IOException, Exception {
|
||||
Entry entry = null;
|
||||
if (splitTrack.getId() != track.getId()
|
||||
|| splitTrack.getLocations().size() < 2) {
|
||||
int numLocations = splitTrack.getLocations().size();
|
||||
if (numLocations < 2) {
|
||||
// Need at least two points for a polyline:
|
||||
Log.w(MyTracksConstants.TAG, "Not uploading too few points");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -495,115 +531,67 @@ public class SendToMyMaps {
|
||||
}
|
||||
|
||||
public SendToMyMaps(Activity context, String mapId, AuthManager auth,
|
||||
long trackId, ProgressIndicator progressIndicator) {
|
||||
long trackId, ProgressIndicator progressIndicator,
|
||||
OnSendCompletedListener onCompletion) {
|
||||
this.context = context;
|
||||
this.mapId = mapId;
|
||||
this.auth = auth;
|
||||
this.trackId = trackId;
|
||||
this.progressIndicator = progressIndicator;
|
||||
this.onCompletion = onCompletion;
|
||||
this.stringUtils = new StringUtils(context);
|
||||
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
|
||||
Log.d(MyTracksConstants.TAG, "Sending to MyMap: trackId = " + trackId);
|
||||
handlerThread = new HandlerThread("SendToMyMaps");
|
||||
handlerThread.start();
|
||||
handler = new Handler(handlerThread.getLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doUpload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOnCompletion(Runnable onCompletion) {
|
||||
this.onCompletion = onCompletion;
|
||||
}
|
||||
|
||||
public String getMapId() {
|
||||
return mapId;
|
||||
}
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public String getStatusMessage() {
|
||||
return statusMessage;
|
||||
Log.d(MyTracksConstants.TAG, "Sending to MyMaps: trackId = " + trackId);
|
||||
doUpload();
|
||||
}
|
||||
|
||||
private void doUpload() {
|
||||
statusMessage = context.getString(R.string.error_sending_to_mymap);
|
||||
success = true;
|
||||
int statusMessageId = R.string.error_sending_to_mymap;
|
||||
boolean success = true;
|
||||
try {
|
||||
gdataConverter = new MyMapsGDataConverter();
|
||||
|
||||
progressIndicator.setProgressValue(1);
|
||||
progressIndicator.setProgressMessage(
|
||||
context.getString(R.string.progress_message_reading_track));
|
||||
R.string.progress_message_reading_track);
|
||||
|
||||
// Get the track meta-data
|
||||
Track track = providerUtils.getTrack(trackId);
|
||||
originalDescription = track.getDescription();
|
||||
String originalDescription = track.getDescription();
|
||||
track.setDescription("<p>" + track.getDescription() + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(track, null, null) + "</p>");
|
||||
wrapper = new MyMapsGDataWrapper(context);
|
||||
wrapper.setAuthManager(auth);
|
||||
wrapper.setRetryOnAuthFailure(true);
|
||||
|
||||
distances = new Vector<Double>();
|
||||
elevations = new Vector<Double>();
|
||||
elevationBuffer =
|
||||
new DoubleBuffer(MyTracksConstants.ELEVATION_SMOOTHING_FACTOR);
|
||||
|
||||
// Create a new map if necessary:
|
||||
if (mapId.equals("new")) {
|
||||
if (!createNewMap(track)) {
|
||||
success = false;
|
||||
}
|
||||
boolean isNewMap = mapId.equals(NEW_MAP_ID);
|
||||
if (isNewMap) {
|
||||
success = createNewMap(track, originalDescription);
|
||||
}
|
||||
|
||||
// Upload all of the segments of the track.
|
||||
// Upload all of the segments of the track plus start/end markers
|
||||
if (success) {
|
||||
if (!uploadAllTrackPoints(track)) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Start end end markers.
|
||||
if (success) {
|
||||
// Put an end marker at the last point of the last valid segment:
|
||||
if (last != null) {
|
||||
track.setDescription("<p>" + originalDescription + "</p><p>"
|
||||
+ stringUtils.generateTrackDescription(
|
||||
track, distances, elevations)
|
||||
+ "</p>");
|
||||
if (!uploadMarker(track, last, false)) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
success = uploadAllTrackPoints(track, originalDescription);
|
||||
}
|
||||
|
||||
// Put waypoints.
|
||||
if (success) {
|
||||
if (!uploadWaypoints(track)) {
|
||||
success = uploadWaypoints(track);
|
||||
if (!success) {
|
||||
Log.w(MyTracksConstants.TAG,
|
||||
"SendToMyMaps: upload waypoints failed.");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (mapId.equals("new")) {
|
||||
statusMessage =
|
||||
context.getString(R.string.status_new_mymap_has_been_created);
|
||||
} else {
|
||||
statusMessage =
|
||||
context.getString(R.string.status_tracks_have_been_uploaded);
|
||||
}
|
||||
statusMessageId = isNewMap
|
||||
? R.string.status_new_mymap_has_been_created
|
||||
: R.string.status_tracks_have_been_uploaded;
|
||||
}
|
||||
Log.d(MyTracksConstants.TAG, "SendToMyMaps: Done: " + success);
|
||||
progressIndicator.setProgressValue(100);
|
||||
@@ -614,10 +602,13 @@ public class SendToMyMaps {
|
||||
wrapper.cleanUp();
|
||||
}
|
||||
|
||||
final boolean finalSuccess = success;
|
||||
final int finalStatusMessageId = statusMessageId;
|
||||
context.runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (onCompletion != null) {
|
||||
onCompletion.run();
|
||||
onCompletion.onSendCompleted(
|
||||
mapId, finalSuccess, finalStatusMessageId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user