diff --git a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java index 3c9f8267b..87efb8d58 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java @@ -144,6 +144,7 @@ public class ChartActivity extends Activity implements TrackDataListener { dataHub.registerTrackDataListener(this, EnumSet.of( ListenerDataType.SELECTED_TRACK_CHANGED, + ListenerDataType.TRACK_UPDATES, ListenerDataType.POINT_UPDATES, ListenerDataType.SAMPLED_OUT_POINT_UPDATES, ListenerDataType.WAYPOINT_UPDATES, @@ -424,7 +425,7 @@ public class ChartActivity extends Activity implements TrackDataListener { this.metricUnits = metric; chartView.setMetricUnits(metric); - + return true; // Reload data } diff --git a/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java b/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java index de33fb381..8aa9387da 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ExportAllTracks.java @@ -189,6 +189,11 @@ public class ExportAllTracks { Log.i(Constants.TAG, "ExportAllTracks: exporting: " + id); TrackWriter writer = TrackWriterFactory.newWriter(activity, providerUtils, id, format); + if (writer == null) { + showToast(R.string.error_track_does_not_exist, Toast.LENGTH_LONG); + return; + } + writer.writeTrack(); if (!writer.wasSuccess()) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java index 4313c2f9d..ad8209b2e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java @@ -905,7 +905,7 @@ public class MyTracks extends TabActivity implements OnTouchListener, * Initiates the process to send tracks to google. * This is called once the user has selected sending options via the * SendToGoogleDialog. - * + * * TODO: Change this whole flow to an actual state machine. */ public void sendToGoogle() { @@ -963,8 +963,12 @@ public class MyTracks extends TabActivity implements OnTouchListener, // Update the map id for this track: try { Track track = providerUtils.getTrack(trackId); - track.setMapId(mapId); - providerUtils.updateTrack(track); + if (track != null) { + track.setMapId(mapId); + providerUtils.updateTrack(track); + } else { + Log.w(TAG, "Updating map id failed."); + } } catch (RuntimeException e) { // If that fails whatever reasons we'll just log an error, but // continue. @@ -1017,15 +1021,19 @@ public class MyTracks extends TabActivity implements OnTouchListener, // Update the table id for this track: try { Track track = providerUtils.getTrack(trackId); - track.setTableId(tableId); - providerUtils.updateTrack(track); + if (track != null) { + track.setTableId(tableId); + providerUtils.updateTrack(track); + } else { + Log.w(TAG, "Updating table id failed."); + } } catch (RuntimeException e) { // If that fails whatever reasons we'll just log an error, but // continue. Log.w(TAG, "Updating table id failed.", e); } } - + onSendToFusionTablesDone(); } }; @@ -1072,7 +1080,7 @@ public class MyTracks extends TabActivity implements OnTouchListener, Log.d(TAG, "Sending to Docs...."); setProgressValue(50); setProgressMessage(R.string.progress_message_sending_docs); - final SendToDocs sender = new SendToDocs(this, + final SendToDocs sender = new SendToDocs(this, authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX), authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId); sendToTrackId = trackId; @@ -1228,6 +1236,11 @@ public class MyTracks extends TabActivity implements OnTouchListener, */ public void saveTrack(long trackId, TrackFileFormat format) { TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format); + if (writer == null) { + dialogManager.showMessageDialog(R.string.error_track_does_not_exist, false); + return; + } + WriteProgressController controller = new WriteProgressController(this, writer); controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() { @Override @@ -1247,6 +1260,10 @@ public class MyTracks extends TabActivity implements OnTouchListener, */ public void sendTrack(long trackId, final TrackFileFormat format) { TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format); + if (writer == null) { + dialogManager.showMessageDialog(R.string.error_track_does_not_exist, false); + return; + } FileUtils fileUtils = new FileUtils(); String extension = format.getExtension(); @@ -1313,17 +1330,17 @@ public class MyTracks extends TabActivity implements OnTouchListener, long getRecordingTrackId() { return sharedPreferences.getLong(getString(R.string.recording_track_key), -1); } - + // @VisibleForTesting SharedPreferences getSharedPreferences() { return sharedPreferences; } - + // @VisibleForTesting static void clearInstance() { instance = null; } - + // @VisibleForTesting ITrackRecordingService getTrackRecordingService() { return trackRecordingService; diff --git a/MyTracks/src/com/google/android/apps/mytracks/WaypointsList.java b/MyTracks/src/com/google/android/apps/mytracks/WaypointsList.java index cbaad0481..9dc0c4295 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/WaypointsList.java +++ b/MyTracks/src/com/google/android/apps/mytracks/WaypointsList.java @@ -1,12 +1,12 @@ /* * Copyright 2009 Google Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -73,15 +73,18 @@ public class WaypointsList extends ListActivity contextPosition = info.position; waypointId = WaypointsList.this.listView.getAdapter() .getItemId(contextPosition); - int type = providerUtils.getWaypoint(info.id).getType(); - menu.add(0, Constants.MENU_SHOW, 0, - R.string.waypointslist_show_waypoint); - menu.add(0, Constants.MENU_EDIT, 0, - R.string.waypointslist_edit_waypoint); - menu.add(0, Constants.MENU_DELETE, 0, - R.string.waypointslist_delete_waypoint).setEnabled( - recordingTrackId < 0 || type == Waypoint.TYPE_WAYPOINT || - info.id != providerUtils.getLastWaypointId(recordingTrackId)); + Waypoint waypoint = providerUtils.getWaypoint(info.id); + if (waypoint != null) { + int type = waypoint.getType(); + menu.add(0, Constants.MENU_SHOW, 0, + R.string.waypointslist_show_waypoint); + menu.add(0, Constants.MENU_EDIT, 0, + R.string.waypointslist_edit_waypoint); + menu.add(0, Constants.MENU_DELETE, 0, + R.string.waypointslist_delete_waypoint).setEnabled( + recordingTrackId < 0 || type == Waypoint.TYPE_WAYPOINT || + info.id != providerUtils.getLastWaypointId(recordingTrackId)); + } } }; @@ -159,7 +162,7 @@ public class WaypointsList extends ListActivity trackId = -1; } - final long firstWaypointId = providerUtils.getFirstWaypointId(trackId); + final long firstWaypointId = providerUtils.getFirstWaypointId(trackId); waypointsCursor = getContentResolver().query( WaypointsColumns.CONTENT_URI, null, WaypointsColumns.TRACKID + "=" + trackId + " AND " @@ -209,7 +212,7 @@ public class WaypointsList extends ListActivity new String[] { WaypointsColumns.NAME, WaypointsColumns.TIME, WaypointsColumns.CATEGORY, WaypointsColumns.TYPE }, new int[] { R.id.waypointslist_item_name, - R.id.waypointslist_item_time, + R.id.waypointslist_item_time, R.id.waypointslist_item_category, R.id.waypointslist_item_icon }); @@ -219,7 +222,7 @@ public class WaypointsList extends ListActivity waypointsCursor.getColumnIndexOrThrow(WaypointsColumns.TYPE); adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() { @Override - public boolean setViewValue(View view, Cursor cursor, int columnIndex) { + public boolean setViewValue(View view, Cursor cursor, int columnIndex) { if (columnIndex == timeIdx) { long time = cursor.getLong(timeIdx); TextView textView = (TextView) view; diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java index 1f7fe6e15..b5bf78e61 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/TrackDataHub.java @@ -17,10 +17,10 @@ package com.google.android.apps.mytracks.content; import static com.google.android.apps.mytracks.Constants.DEFAULT_MIN_REQUIRED_ACCURACY; import static com.google.android.apps.mytracks.Constants.MAX_DISPLAYED_WAYPOINTS_POINTS; -import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_POINTS; import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS; import static com.google.android.apps.mytracks.Constants.MAX_NETWORK_AGE_MS; import static com.google.android.apps.mytracks.Constants.TAG; +import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_POINTS; import com.google.android.apps.mytracks.content.DataSourceManager.DataSourceListener; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.DoubleBufferedLocationFactory; @@ -40,7 +40,6 @@ import android.location.LocationManager; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; -import android.widget.Toast; import java.util.Collections; import java.util.EnumSet; @@ -791,10 +790,6 @@ public class TrackDataHub { public void run() { for (TrackDataListener listener : listeners) { listener.onSelectedTrackChanged(track, isRecordingSelected()); - - if (track != null) { - listener.onTrackUpdated(track); - } } } }); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java index eeb769b88..fd2c517b7 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToFusionTables.java @@ -179,6 +179,11 @@ public class SendToFusionTables implements Runnable { // Get the track meta-data Track track = providerUtils.getTrack(trackId); + if (track == null) { + Log.w(Constants.TAG, "Cannot get track."); + return; + } + String originalDescription = track.getDescription(); // Create a new table: @@ -207,7 +212,6 @@ public class SendToFusionTables implements Runnable { Log.d(Constants.TAG, "SendToFusionTables: Done: " + success); progressIndicator.setProgressValue(PROGRESS_COMPLETE); } finally { - final boolean finalSuccess = success; final int finalStatusMessageId = statusMessageId; context.runOnUiThread(new Runnable() { @@ -304,7 +308,7 @@ public class SendToFusionTables implements Runnable { Cursor locationsCursor = providerUtils.getLocationsCursor(track.getId(), 0, -1, false); try { - if (!locationsCursor.moveToFirst()) { + if (locationsCursor == null || !locationsCursor.moveToFirst()) { Log.w(Constants.TAG, "Unable to get any points to upload"); return false; } @@ -391,7 +395,9 @@ public class SendToFusionTables implements Runnable { return true; } finally { - locationsCursor.close(); + if (locationsCursor != null) { + locationsCursor.close(); + } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java index ffc895da6..f451078d3 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToMyMaps.java @@ -1,12 +1,12 @@ /* * Copyright 2008 Google Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -76,7 +76,7 @@ public class SendToMyMaps implements Runnable { public interface OnSendCompletedListener { void onSendCompleted(String mapId, boolean success, int statusMessage); } - + public SendToMyMaps(Activity context, String mapId, AuthManager auth, long trackId, ProgressIndicator progressIndicator, OnSendCompletedListener onCompletion) { @@ -103,15 +103,20 @@ public class SendToMyMaps implements Runnable { progressIndicator.setProgressValue(1); progressIndicator.setProgressMessage( R.string.progress_message_reading_track); - + // Get the track meta-data Track track = providerUtils.getTrack(trackId); + if (track == null) { + Log.w(Constants.TAG, "Cannot get track."); + return; + } + String originalDescription = track.getDescription(); track.setDescription("
" + track.getDescription() + "
" + stringUtils.generateTrackDescription(track, null, null) + "
"); mapsClient = new MapsFacade(context, auth); - + // Create a new map if necessary: boolean isNewMap = mapId.equals(NEW_MAP_ID); if (isNewMap) { @@ -166,7 +171,7 @@ public class SendToMyMaps implements Runnable { Log.w(TAG, "SendToMyMaps: upload waypoints failed."); } } - + if (success) { statusMessageId = isNewMap ? R.string.status_new_mymap_has_been_created @@ -178,7 +183,7 @@ public class SendToMyMaps implements Runnable { if (mapsClient != null) { mapsClient.cleanUp(); } - + final boolean finalSuccess = success; final int finalStatusMessageId = statusMessageId; context.runOnUiThread(new Runnable() { @@ -206,17 +211,17 @@ public class SendToMyMaps implements Runnable { Cursor locationsCursor = providerUtils.getLocationsCursor(track.getId(), 0, -1, false); try { - if (!locationsCursor.moveToFirst()) { + if (locationsCursor == null || !locationsCursor.moveToFirst()) { Log.w(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)); @@ -224,12 +229,12 @@ public class SendToMyMaps implements Runnable { "Using elevation sampling factor: " + elevationSamplingFrequency + " on " + totalLocations); double totalDistance = 0; - + Vector" + originalDescription + "
" + stringUtils.generateTrackDescription( track, distances, elevations) + "
"); - return mapsClient.uploadMarker(mapId, track.getName(), track.getDescription(), + return mapsClient.uploadMarker(mapId, track.getName(), track.getDescription(), lastLocation, false); } - + return true; } finally { - locationsCursor.close(); + if (locationsCursor != null) { + locationsCursor.close(); + } } } @@ -306,17 +313,17 @@ public class SendToMyMaps implements Runnable { progressIndicator.setProgressMessage( R.string.progress_message_preparing_track); updateProgress(); - + int numLocations = locations.size(); if (numLocations < 2) { Log.d(TAG, "Not preparing/uploading too few points"); totalLocationsUploaded += numLocations; return true; } - + // Prepare/pre-process the points ArrayList