diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml
index 33135fe33..db49bb3d7 100755
--- a/MyTracks/AndroidManifest.xml
+++ b/MyTracks/AndroidManifest.xml
@@ -129,6 +129,7 @@ limitations under the License.
+
@@ -191,7 +192,6 @@ limitations under the License.
-
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
index a78d59c55..442016e55 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
@@ -84,6 +84,25 @@ public class MapActivity extends com.google.android.maps.MapActivity
*/
private boolean keepMyLocationVisible;
+ /**
+ * The ID of a track on which we want to show a waypoint.
+ * The waypoint will be shown as soon as the track is loaded.
+ */
+ private long showWaypointTrackId;
+
+ /**
+ * The ID of a waypoint which we want to show.
+ * The waypoint will be shown as soon as its track is loaded.
+ */
+ private long showWaypointId;
+
+ /**
+ * The track that's currently selected.
+ * This differs from {@link TrackDataHub#getSelectedTrackId} in that this one is only set after
+ * actual track data has been received.
+ */
+ private long selectedTrackId;
+
/**
* The current pointer location.
* This is kept to quickly center on it when the user requests.
@@ -330,6 +349,47 @@ public class MapActivity extends com.google.android.maps.MapActivity
}
}
+ /**
+ * Zooms and pans the map so that the given waypoint is visible, when the given track is loaded.
+ * If the track is already loaded, it does that immediately.
+ *
+ * @param trackId the ID of the track on which to show the waypoint
+ * @param waypointId the ID of the waypoint to show
+ */
+ public void showWaypoint(long trackId, long waypointId) {
+ synchronized (this) {
+ if (trackId == selectedTrackId) {
+ showWaypoint(waypointId);
+ return;
+ }
+
+ showWaypointTrackId = trackId;
+ showWaypointId = waypointId;
+ }
+ }
+
+ /**
+ * Does the proper zooming/panning for a just-loaded track.
+ * This may be either zooming to a waypoint that has been previously selected, or
+ * zooming to the whole track.
+ *
+ * @param track the loaded track
+ */
+ private void zoomLoadedTrack(Track track) {
+ synchronized (this) {
+ if (track.getId() == showWaypointTrackId) {
+ // There's a waypoint to show in this track.
+ showWaypoint(showWaypointId);
+
+ showWaypointId = 0L;
+ showWaypointTrackId = 0L;
+ } else {
+ // Zoom out to show the whole track.
+ zoomMapToBoundaries(track);
+ }
+ }
+ }
+
@Override
public void onSelectedTrackChanged(final Track track, final boolean isRecording) {
runOnUiThread(new Runnable() {
@@ -343,7 +403,12 @@ public class MapActivity extends com.google.android.maps.MapActivity
if (trackSelected) {
busyPane.setVisibility(View.VISIBLE);
- zoomMapToBoundaries(track);
+ synchronized (this) {
+ // Need to get the track ID only at this point, to prevent a race condition
+ // among showWaypoint, zoomLoadedTrack and dataHub.loadTrack.
+ selectedTrackId = track.getId();
+ zoomLoadedTrack(track);
+ }
mapOverlay.setShowEndMarker(!isRecording);
busyPane.setVisibility(View.GONE);
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
index e5b5287b1..4de41f449 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
@@ -21,7 +21,9 @@ import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TracksColumns;
+import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
+import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.io.file.TempFileCleaner;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.ServiceUtils;
@@ -67,7 +69,7 @@ import android.widget.Toast;
@SuppressWarnings("deprecation")
public class MyTracks extends TabActivity implements OnTouchListener {
private static final int DIALOG_EULA_ID = 0;
-
+
private TrackDataHub dataHub;
/**
@@ -202,7 +204,7 @@ public class MyTracks extends TabActivity implements OnTouchListener {
showDialog(DIALOG_EULA_ID);
}
}
-
+
@Override
protected void onStart() {
Log.d(TAG, "MyTracks.onStart");
@@ -222,6 +224,19 @@ public class MyTracks extends TabActivity implements OnTouchListener {
&& UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
long trackId = ContentUris.parseId(data);
dataHub.loadTrack(trackId);
+ } else if (Intent.ACTION_VIEW.equals(action)
+ && WaypointsColumns.CONTENT_ITEMTYPE.equals(intent.getType())
+ && UriUtils.matchesContentUri(data, WaypointsColumns.CONTENT_URI)) {
+ // TODO(rdamazio): Waypoint URIs should be base/trackid/waypointid
+ long waypointId = ContentUris.parseId(data);
+ Waypoint waypoint = providerUtils.getWaypoint(waypointId);
+ long trackId = waypoint.getTrackId();
+
+ // Request that the waypoint is shown (now or when the right track is loaded).
+ showWaypoint(trackId, waypointId);
+
+ // Load the right track, if not loaded already.
+ dataHub.loadTrack(trackId);
}
}
@@ -296,7 +311,7 @@ public class MyTracks extends TabActivity implements OnTouchListener {
return null;
}
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -367,14 +382,9 @@ public class MyTracks extends TabActivity implements OnTouchListener {
}
case Constants.SHOW_WAYPOINT: {
if (results != null) {
- final long waypointId = results.getLongExtra("waypointid", -1);
+ final long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1);
if (waypointId >= 0) {
- MapActivity map =
- (MapActivity) getLocalActivityManager().getActivity("tab1");
- if (map != null) {
- getTabHost().setCurrentTab(0);
- map.showWaypoint(waypointId);
- }
+ showWaypoint(trackId, waypointId);
}
}
break;
@@ -390,6 +400,17 @@ public class MyTracks extends TabActivity implements OnTouchListener {
}
}
+ private void showWaypoint(long trackId, long waypointId) {
+ MapActivity map =
+ (MapActivity) getLocalActivityManager().getActivity("tab1");
+ if (map != null) {
+ getTabHost().setCurrentTab(0);
+ map.showWaypoint(trackId, waypointId);
+ } else {
+ Log.e(TAG, "Couldnt' get map tab");
+ }
+ }
+
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
diff --git a/MyTracks/src/com/google/android/apps/mytracks/SearchActivity.java b/MyTracks/src/com/google/android/apps/mytracks/SearchActivity.java
index 3d2f2d117..05e37d90d 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/SearchActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/SearchActivity.java
@@ -73,16 +73,16 @@ public class SearchActivity extends ListActivity {
new Comparator() {
@Override
public int compare(ScoredResult r1, ScoredResult r2) {
+ // Score ordering.
int scoreDiff = (int) (r2.score - r1.score);
if (scoreDiff != 0) {
return scoreDiff;
}
- if (r1.track != null) {
- return (int) (r2.track.getId() - r1.track.getId());
- } else {
- return (int) (r2.waypoint.getId() - r1.waypoint.getId());
- }
+ // Arbitrary ordering, by ID.
+ long id1 = r1.track != null ? r1.track.getId() : r1.waypoint.getId();
+ long id2 = r2.track != null ? r2.track.getId() : r2.waypoint.getId();
+ return (int) (id2 - id1);
}
};
@@ -421,16 +421,18 @@ public class SearchActivity extends ListActivity {
protected void onListItemClick(ListView l, View v, int position, long id) {
@SuppressWarnings("unchecked")
Map clickedData = (Map) getListAdapter().getItem(position);
- long trackId = (Long) clickedData.get("trackId");
+
+ Intent intent = new Intent(Intent.ACTION_VIEW);
if (clickedData.containsKey("waypointId")) {
long waypointId = (Long) clickedData.get("waypointId");
- // TODO: Add support for loading track + showing waypoint in MyTracks.java.
+ Uri uri = ContentUris.withAppendedId(WaypointsColumns.CONTENT_URI, waypointId);
+ intent.setDataAndType(uri, WaypointsColumns.CONTENT_ITEMTYPE);
} else {
- Intent intent = new Intent(Intent.ACTION_VIEW);
+ long trackId = (Long) clickedData.get("trackId");
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
- startActivity(intent);
}
+ startActivity(intent);
}
private static double squash(double timeAgoHours) {