diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml
index 40c852901..ed3a78083 100755
--- a/MyTracks/AndroidManifest.xml
+++ b/MyTracks/AndroidManifest.xml
@@ -90,6 +90,13 @@ limitations under the License.
android:label="@string/elevation_label"
android:exported="false" />
+
+
+
diff --git a/MyTracks/src/com/google/android/apps/mytracks/AccountChooser.java b/MyTracks/src/com/google/android/apps/mytracks/AccountChooser.java
index 7a648a304..c26434440 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/AccountChooser.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/AccountChooser.java
@@ -29,7 +29,7 @@ import android.util.Log;
* @author Sandor Dornbush
*/
public class AccountChooser {
-
+
/**
* The last selected account.
*/
@@ -68,13 +68,13 @@ public class AccountChooser {
handler.handleAccountSelected(accounts[0]);
return;
}
-
+
// TODO This should be read out of a preference.
if (selectedAccount != null) {
handler.handleAccountSelected(selectedAccount);
return;
}
-
+
// Let the user choose.
Log.e(Constants.TAG, "Multiple matching accounts found.");
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
diff --git a/MyTracks/src/com/google/android/apps/mytracks/Constants.java b/MyTracks/src/com/google/android/apps/mytracks/Constants.java
index c3fc58acf..063bb6679 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/Constants.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/Constants.java
@@ -50,7 +50,7 @@ public abstract class Constants {
public static final int AUTHENTICATE_TO_DOCLIST = 10;
public static final int AUTHENTICATE_TO_TRIX = 11;
public static final int DELETE_TRACK = 13;
- public static final int SEND_TO_GOOGLE_DIALOG = 14;
+ public static final int SEND_TO_GOOGLE = 14;
public static final int SHARE_LINK = 15;
public static final int SHARE_GPX_FILE = 16;
public static final int SHARE_KML_FILE = 17;
@@ -190,7 +190,7 @@ public abstract class Constants {
public static int getActionFromMenuId(int menuId) {
switch (menuId) {
case Constants.MENU_SEND_TO_GOOGLE:
- return Constants.SEND_TO_GOOGLE_DIALOG;
+ return Constants.SEND_TO_GOOGLE;
case Constants.MENU_EDIT:
return Constants.EDIT_DETAILS;
case Constants.MENU_DELETE:
diff --git a/MyTracks/src/com/google/android/apps/mytracks/DialogManager.java b/MyTracks/src/com/google/android/apps/mytracks/DialogManager.java
index 3b9d67377..722530884 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/DialogManager.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/DialogManager.java
@@ -24,6 +24,8 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager.BadTokenException;
@@ -37,7 +39,6 @@ public class DialogManager {
public static final int DIALOG_IMPORT_PROGRESS = 2;
public static final int DIALOG_PROGRESS = 3;
- public static final int DIALOG_SEND_TO_GOOGLE = 4;
private ProgressDialog progressDialog;
private ProgressDialog importProgressDialog;
@@ -69,21 +70,10 @@ public class DialogManager {
progressDialog.setMax(100);
progressDialog.setProgress(10);
return progressDialog;
- case DIALOG_SEND_TO_GOOGLE:
- sendToGoogleDialog = new SendDialog(activity);
- return sendToGoogleDialog;
}
return null;
}
- protected void onPrepareDialog(int id, Dialog dialog) {
- switch (id) {
- case DIALOG_SEND_TO_GOOGLE:
- activity.resetSendToGoogleStatus();
- break;
- }
- }
-
public void setProgressMessage(final String message) {
activity.runOnUiThread(new Runnable() {
public void run() {
@@ -126,19 +116,24 @@ public class DialogManager {
public void showMessageDialog(final int message, final boolean success) {
activity.runOnUiThread(new Runnable() {
public void run() {
- AlertDialog dialog = null;
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(activity.getString(message));
- builder.setNegativeButton(activity.getString(R.string.ok), null);
- builder.setIcon(success ? android.R.drawable.ic_dialog_info :
- android.R.drawable.ic_dialog_alert);
- builder.setTitle(success ? R.string.success : R.string.error);
- dialog = builder.create();
- dialog.show();
+ showMessageDialog(activity, message, success, null);
}
});
}
+ public static void showMessageDialog(
+ Context ctx, int message, boolean success, DialogInterface.OnClickListener okListener) {
+ AlertDialog dialog = null;
+ AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
+ builder.setMessage(message);
+ builder.setNeutralButton(R.string.ok, okListener);
+ builder.setIcon(success ? android.R.drawable.ic_dialog_info :
+ android.R.drawable.ic_dialog_alert);
+ builder.setTitle(success ? R.string.success : R.string.error);
+ dialog = builder.create();
+ dialog.show();
+ }
+
/**
* Just like showDialog, but will catch a {@link BadTokenException} that
* sometimes (very rarely) gets thrown. This might happen if the user hits
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
index 25af090a4..4ee5d26cd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
@@ -23,6 +23,8 @@ import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
import com.google.android.apps.mytracks.content.TrackDataListener;
import com.google.android.apps.mytracks.content.Waypoint;
+import com.google.android.apps.mytracks.io.file.SaveActivity;
+import com.google.android.apps.mytracks.io.sendtogoogle.SendActivity;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiFeatures;
@@ -391,13 +393,27 @@ public class MapActivity extends com.google.android.maps.MapActivity
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
- if (!super.onMenuItemSelected(featureId, item)) {
- MyTracks.getInstance().onActivityResult(
- Constants.getActionFromMenuId(item.getItemId()), RESULT_OK,
- new Intent());
- return true;
+ switch (item.getItemId()) {
+ case Constants.MENU_SEND_TO_GOOGLE:
+ SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), false);
+ return true;
+ case Constants.MENU_SHARE_LINK:
+ SendActivity.sendToGoogle(this, dataHub.getSelectedTrackId(), true);
+ return true;
+ case Constants.MENU_SAVE_GPX_FILE:
+ case Constants.MENU_SAVE_KML_FILE:
+ case Constants.MENU_SAVE_CSV_FILE:
+ case Constants.MENU_SAVE_TCX_FILE:
+ case Constants.MENU_SHARE_GPX_FILE:
+ case Constants.MENU_SHARE_KML_FILE:
+ case Constants.MENU_SHARE_CSV_FILE:
+ case Constants.MENU_SHARE_TCX_FILE:
+ SaveActivity.handleExportTrackAction(this, dataHub.getSelectedTrackId(),
+ Constants.getActionFromMenuId(item.getItemId()));
+ return true;
+ default:
+ return super.onMenuItemSelected(featureId, item);
}
- return false;
}
@Override
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyMapsList.java b/MyTracks/src/com/google/android/apps/mytracks/MyMapsList.java
index 7b74ac606..0ee852e29 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyMapsList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyMapsList.java
@@ -25,11 +25,7 @@ import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
@@ -42,29 +38,12 @@ import android.widget.TextView;
* @author Rodrigo Damazio
*/
public class MyMapsList extends Activity implements MapsFacade.MapsListCallback {
- private static final int MENU_OPEN = 0;
- private static final int MENU_SHARE = 2;
private static final int GET_LOGIN = 1;
private MapsFacade mapsClient;
private AuthManager auth;
private MyMapsListAdapter listAdapter;
- private int contextPosition;
-
- private final OnCreateContextMenuListener contextMenuListener =
- new OnCreateContextMenuListener() {
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- AdapterView.AdapterContextMenuInfo info =
- (AdapterView.AdapterContextMenuInfo) menuInfo;
- contextPosition = info.position;
- menu.add(0, MENU_OPEN, 0, R.string.open_map);
- menu.add(0, MENU_SHARE, 0, R.string.share_map);
- }
- };
-
private final OnItemClickListener clickListener =
new OnItemClickListener() {
@Override
@@ -91,7 +70,6 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
ListView list = (ListView) findViewById(R.id.maplist);
list.setOnItemClickListener(clickListener);
- list.setOnCreateContextMenuListener(contextMenuListener);
list.setAdapter(listAdapter);
startLogin();
@@ -101,7 +79,8 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
// Starts in the UI thread.
// TODO fix this for non-froyo devices.
if (AuthManagerFactory.useModernAuthManager()) {
- MyTracks.getInstance().getAccountChooser().chooseAccount(
+ AccountChooser accountChooser = new AccountChooser();
+ accountChooser.chooseAccount(
MyMapsList.this,
new AccountChooser.AccountHandler() {
@Override
@@ -183,27 +162,4 @@ public class MyMapsList extends Activity implements MapsFacade.MapsListCallback
}
super.onActivityResult(requestCode, resultCode, data);
}
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- switch (item.getItemId()) {
- case MENU_OPEN:
- clickListener.onItemClick(null, null, contextPosition, 0);
- return true;
- case MENU_SHARE:
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType("text/plain");
- shareIntent.putExtra(Intent.EXTRA_SUBJECT,
- getText(R.string.share_map_subject));
- String[] listItem = (String[]) listAdapter.getMapListingArray(contextPosition);
- shareIntent.putExtra(Intent.EXTRA_TEXT, String.format(
- getText(R.string.share_map_body_format).toString(),
- listItem[1],
- MapsFacade.buildMapUrl(listItem[0])));
- startActivity(Intent.createChooser(shareIntent,
- getText(R.string.share_map).toString()));
- return true;
- }
- return false;
- }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
index 4313c2f9d..de3fc31bb 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java
@@ -17,36 +17,16 @@ package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.TAG;
import static com.google.android.apps.mytracks.DialogManager.DIALOG_IMPORT_PROGRESS;
-import static com.google.android.apps.mytracks.DialogManager.DIALOG_PROGRESS;
-import static com.google.android.apps.mytracks.DialogManager.DIALOG_SEND_TO_GOOGLE;
-import com.google.android.accounts.Account;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
-import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
-import com.google.android.apps.mytracks.io.AuthManager;
-import com.google.android.apps.mytracks.io.AuthManagerFactory;
-import com.google.android.apps.mytracks.io.SendToDocs;
-import com.google.android.apps.mytracks.io.SendToFusionTables;
-import com.google.android.apps.mytracks.io.SendToFusionTables.OnSendCompletedListener;
-import com.google.android.apps.mytracks.io.SendToMyMaps;
import com.google.android.apps.mytracks.io.file.GpxImporter;
import com.google.android.apps.mytracks.io.file.TempFileCleaner;
-import com.google.android.apps.mytracks.io.file.TrackWriter;
-import com.google.android.apps.mytracks.io.file.TrackWriterFactory;
-import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
-import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
-import com.google.android.apps.mytracks.io.mymaps.MyMapsConstants;
-import com.google.android.apps.mytracks.io.sendtogoogle.ResultDialogFactory;
-import com.google.android.apps.mytracks.io.sendtogoogle.SendDialog;
-import com.google.android.apps.mytracks.io.sendtogoogle.SendResult;
-import com.google.android.apps.mytracks.io.sendtogoogle.SendType;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.util.ApiFeatures;
-import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
@@ -60,13 +40,9 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Resources;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -79,13 +55,9 @@ import android.widget.RelativeLayout;
import android.widget.TabHost;
import android.widget.Toast;
-import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
@@ -98,21 +70,7 @@ import org.xml.sax.SAXException;
*/
public class MyTracks extends TabActivity implements OnTouchListener,
ProgressIndicator {
- /**
- * Singleton instance
- */
- private static MyTracks instance;
-
private TrackDataHub dataHub;
- private ChartActivity chartActivity;
-
- /*
- * Authentication
- */
- private AuthManager auth;
- private final HashMap authMap =
- new HashMap();
- private final AccountChooser accountChooser = new AccountChooser();
/*
* Dialogs manager.
@@ -124,21 +82,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
*/
private MenuManager menuManager;
- /*
- * Information on upload success to MyMaps/Docs.
- * Used by SendToGoogleResultDialog.
- */
-
- public long sendToTrackId = -1;
- public boolean sendToMyMapsSuccess = false;
- public boolean sendToFusionTablesSuccess = false;
- public boolean sendToDocsSuccess = false;
- public String sendToMyMapsMapId;
- public String sendToMyMapsMessage = "";
- public String sendToFusionTablesTableId;
- public String sendToFusionTablesMessage = "";
- public String sendToDocsMessage = "";
-
/**
* True if a new track should be created after the track recording service
* binds.
@@ -147,11 +90,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
private ITrackRecordingService trackRecordingService;
- /**
- * Does the user want to share the current track.
- */
- private boolean shareRequested = false;
-
/**
* Utilities to deal with the database.
*/
@@ -205,10 +143,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
};
- public static MyTracks getInstance() {
- return instance;
- }
-
/**
* Checks whether we have a track recording session in progress.
* In some cases, when the service has crashed or has been restarted
@@ -318,6 +252,53 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
+ private void importGpxFile(final String fileName) {
+ dialogManager.showDialogSafely(DIALOG_IMPORT_PROGRESS);
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ int message = R.string.success;
+
+ long[] trackIdsImported = null;
+
+ try {
+ try {
+ InputStream is = new FileInputStream(fileName);
+ trackIdsImported = GpxImporter.importGPXFile(is, providerUtils);
+ } catch (SAXException e) {
+ Log.e(TAG, "Caught an unexpected exception.", e);
+ message = R.string.error_generic;
+ } catch (ParserConfigurationException e) {
+ Log.e(TAG, "Caught an unexpected exception.", e);
+ message = R.string.error_generic;
+ } catch (IOException e) {
+ Log.e(TAG, "Caught an unexpected exception.", e);
+ message = R.string.error_unable_to_read_file;
+ } catch (NullPointerException e) {
+ Log.e(TAG, "Caught an unexpected exception.", e);
+ message = R.string.error_invalid_gpx_format;
+ } catch (OutOfMemoryError e) {
+ Log.e(TAG, "Caught an unexpected exception.", e);
+ message = R.string.error_out_of_memory;
+ }
+ if (trackIdsImported != null && trackIdsImported.length > 0) {
+ // select last track from import file
+ dataHub.loadTrack(trackIdsImported[trackIdsImported.length - 1]);
+ } else {
+ dialogManager.showMessageDialog(message, false/* success */);
+ }
+ } finally {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ dismissDialog(DIALOG_IMPORT_PROGRESS);
+ }
+ });
+ }
+ }
+ };
+ t.start();
+ }
+
@Override
protected void onDestroy() {
Log.d(TAG, "MyTracks.onDestroy");
@@ -410,12 +391,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
return dialogManager.onCreateDialog(id, null);
}
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- super.onPrepareDialog(id, dialog);
- dialogManager.onPrepareDialog(id, dialog);
- }
-
/*
* Key events:
* ===========
@@ -442,19 +417,12 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public void onActivityResult(int requestCode, int resultCode,
final Intent results) {
Log.d(TAG, "MyTracks.onActivityResult");
- TrackFileFormat exportFormat = null;
long trackId = dataHub.getSelectedTrackId();
if (results != null) {
trackId = results.getLongExtra("trackid", trackId);
}
switch (requestCode) {
- case Constants.GET_LOGIN: {
- if (resultCode != RESULT_OK || auth == null || !auth.authResult(resultCode, results)) {
- dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
- }
- break;
- }
case Constants.SHOW_TRACK: {
if (results != null) {
if (trackId >= 0) {
@@ -497,118 +465,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
break;
}
- case Constants.SEND_TO_GOOGLE_DIALOG: {
- shareRequested = false;
- dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
- break;
- }
- case Constants.GET_MAP: {
- // User picked a map to upload to
- if (resultCode == RESULT_OK) {
- results.putExtra("trackid", dataHub.getSelectedTrackId());
- if (results.hasExtra("mapid")) {
- sendToMyMapsMapId = results.getStringExtra("mapid");
- }
- authenticateToGoogleMaps(results);
- } else {
- onSendToGoogleDone();
- }
- break;
- }
- case Constants.AUTHENTICATE_TO_MY_MAPS: {
- // Authenticated with Google My Maps
- if (results != null && resultCode == RESULT_OK) {
- final String mapId;
- if (results.hasExtra("mapid")) {
- mapId = results.getStringExtra("mapid");
- } else {
- mapId = "new";
- }
-
- sendToGoogleMaps(trackId, mapId);
- } else {
- onSendToGoogleDone();
- }
- break;
- }
- case Constants.AUTHENTICATE_TO_FUSION_TABLES: {
- // Authenticated with Google Fusion Tables
- if (results != null && resultCode == RESULT_OK) {
- sendToFusionTables(trackId);
- } else {
- onSendToGoogleDone();
- }
- break;
- }
- case Constants.AUTHENTICATE_TO_DOCLIST: {
- // Authenticated with Google Docs
- if (resultCode == RESULT_OK) {
- authenticateToGoogleTrix();
- } else {
- onSendToGoogleDone();
- }
- break;
- }
- case Constants.AUTHENTICATE_TO_TRIX: {
- // Authenticated with Trix
- if (resultCode == RESULT_OK) {
- sendToGoogleDocs(trackId);
- } else {
- onSendToGoogleDone();
- }
- break;
- }
- case Constants.SAVE_GPX_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
- //$FALL-THROUGH$
- case Constants.SAVE_KML_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
- //$FALL-THROUGH$
- case Constants.SAVE_CSV_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
- //$FALL-THROUGH$
- case Constants.SAVE_TCX_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
-
- if (results != null && resultCode == Activity.RESULT_OK) {
- if (trackId >= 0) {
- saveTrack(trackId, exportFormat);
- }
- }
- break;
- case Constants.SHARE_LINK: {
- Track selectedTrack = providerUtils.getTrack(dataHub.getSelectedTrackId());
- if (selectedTrack != null) {
- if (!TextUtils.isEmpty(selectedTrack.getMapId())) {
- shareLinkToMap(MapsFacade.buildMapUrl(selectedTrack.getMapId()));
- } else if (!TextUtils.isEmpty(selectedTrack.getTableId())) {
- shareLinkToMap(getFusionTablesUrl(dataHub.getSelectedTrackId()));
- } else {
- shareRequested = true;
- dialogManager.showDialogSafely(DIALOG_SEND_TO_GOOGLE);
- }
- }
- break;
- }
- case Constants.SHARE_GPX_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.GPX; }
- //$FALL-THROUGH$
- case Constants.SHARE_KML_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.KML; }
- //$FALL-THROUGH$
- case Constants.SHARE_CSV_FILE:
- if (exportFormat == null) { exportFormat = TrackFileFormat.CSV; }
- //$FALL-THROUGH$
- case Constants.SHARE_TCX_FILE: {
- if (exportFormat == null) { exportFormat = TrackFileFormat.TCX; }
-
- if (results != null && resultCode == Activity.RESULT_OK) {
- if (trackId >= 0) {
- sendTrack(trackId, exportFormat);
- }
- }
- break;
- }
case Constants.CLEAR_MAP: {
dataHub.unloadCurrentTrack();
break;
@@ -631,68 +487,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
return false;
}
-
- /**
- * Resets status information for sending to MyMaps/Docs.
- */
- public void resetSendToGoogleStatus() {
- sendToMyMapsMapId = null;
- sendToMyMapsMessage = "";
- sendToMyMapsSuccess = true;
- sendToFusionTablesMessage = "";
- sendToFusionTablesSuccess = true;
- sendToDocsMessage = "";
- sendToDocsSuccess = true;
- sendToFusionTablesTableId = null;
- }
-
- private void importGpxFile(final String fileName) {
- dialogManager.showDialogSafely(DIALOG_IMPORT_PROGRESS);
- Thread t = new Thread() {
- @Override
- public void run() {
- int message = R.string.success;
-
- long[] trackIdsImported = null;
-
- try {
- try {
- InputStream is = new FileInputStream(fileName);
- trackIdsImported = GpxImporter.importGPXFile(is, providerUtils);
- } catch (SAXException e) {
- Log.e(TAG, "Caught an unexpected exception.", e);
- message = R.string.error_generic;
- } catch (ParserConfigurationException e) {
- Log.e(TAG, "Caught an unexpected exception.", e);
- message = R.string.error_generic;
- } catch (IOException e) {
- Log.e(TAG, "Caught an unexpected exception.", e);
- message = R.string.error_unable_to_read_file;
- } catch (NullPointerException e) {
- Log.e(TAG, "Caught an unexpected exception.", e);
- message = R.string.error_invalid_gpx_format;
- } catch (OutOfMemoryError e) {
- Log.e(TAG, "Caught an unexpected exception.", e);
- message = R.string.error_out_of_memory;
- }
- if (trackIdsImported != null && trackIdsImported.length > 0) {
- // select last track from import file
- dataHub.loadTrack(trackIdsImported[trackIdsImported.length - 1]);
- } else {
- dialogManager.showMessageDialog(message, false/* success */);
- }
- } finally {
- runOnUiThread(new Runnable() {
- public void run() {
- dismissDialog(DIALOG_IMPORT_PROGRESS);
- }
- });
- }
- }
- };
- t.start();
- }
-
// ProgressIndicator implementation
@Override
@@ -710,29 +504,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
dialogManager.setProgressValue(percent);
}
- /**
- * Shares a link to a My Map or Fusion Table via external app (email, gmail, ...)
- * A chooser with apps that support text/plain will be shown to the user.
- */
- public void shareLinkToMap(String url) {
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.setType("text/plain");
- shareIntent.putExtra(Intent.EXTRA_SUBJECT,
- getResources().getText(R.string.share_map_subject).toString());
-
- boolean shareUrlOnly = true;
- if (sharedPreferences != null) {
- shareUrlOnly = sharedPreferences.getBoolean(
- getString(R.string.share_url_only_key), false);
- }
-
- String msg = shareUrlOnly ? url : String.format(
- getResources().getText(R.string.share_map_body_format).toString(), url);
- shareIntent.putExtra(Intent.EXTRA_TEXT, msg);
- startActivity(Intent.createChooser(shareIntent,
- getResources().getText(R.string.share_map).toString()));
- }
-
/**
* Deletes the track with the given id.
* Prompts the user if he want to really delete the track first.
@@ -787,54 +558,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
- /**
- * Initializes the authentication manager which obtains an authentication
- * token, prompting the user for a login and password if needed.
- */
- private void authenticate(final Intent results, final int requestCode,
- final String service) {
- auth = authMap.get(service);
- if (auth == null) {
- Log.i(TAG, "Creating a new authentication for service: " + service);
- auth = AuthManagerFactory.getAuthManager(this,
- Constants.GET_LOGIN,
- null,
- true,
- service);
- authMap.put(service, auth);
- }
- Log.d(TAG, "Logging in to " + service + "...");
- if (AuthManagerFactory.useModernAuthManager()) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- accountChooser.chooseAccount(MyTracks.this,
- new AccountChooser.AccountHandler() {
- @Override
- public void handleAccountSelected(Account account) {
- if (account == null) {
- dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
- return;
- }
- doLogin(results, requestCode, service, account);
- }
- });
- }
- });
- } else {
- doLogin(results, requestCode, service, null);
- }
- }
-
- private void doLogin(final Intent results, final int requestCode,
- final String service, final Account account) {
- auth.doLogin(new Runnable() {
- public void run() {
- Log.d(TAG, "Loggin success for " + service + "!");
- onActivityResult(requestCode, RESULT_OK, results);
- }
- }, account);
- }
private void startRecordingNewTrack(
ITrackRecordingService trackRecordingService) {
@@ -900,290 +623,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
trackRecordingService = null;
}
-
- /**
- * 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() {
- SendDialog sendToGoogleDialog =
- dialogManager.getSendToGoogleDialog();
- if (sendToGoogleDialog == null) {
- return;
- }
- setProgressValue(0);
- clearProgressMessage();
- dialogManager.showDialogSafely(DIALOG_PROGRESS);
-
- if (sendToGoogleDialog.getSendToMyMaps()) {
- sendToGoogleMapsOrPickMap(sendToGoogleDialog);
- } else if (sendToGoogleDialog.getSendToFusionTables()) {
- authenticateToFusionTables(null);
- } else if (sendToGoogleDialog.getSendToDocs()) {
- authenticateToGoogleDocs();
- } else {
- Log.w(TAG, "Nowhere to upload to");
- onSendToGoogleDone();
- }
- }
-
- private void sendToGoogleMapsOrPickMap(SendDialog sendToGoogleDialog) {
- if (!sendToGoogleDialog.getCreateNewMap()) {
- // Ask the user to choose a map to upload into
- Intent listIntent = new Intent(this, MyMapsList.class);
- startActivityForResult(listIntent, Constants.GET_MAP);
- // The callback for GET_MAP calls authenticateToGoogleMaps
- } else {
- authenticateToGoogleMaps(null);
- }
- }
-
- private void authenticateToGoogleMaps(Intent results) {
- if (results == null) { results = new Intent(); }
-
- setProgressValue(0);
- setProgressMessage(
- R.string.progress_message_authenticating_mymaps);
- authenticate(results, Constants.AUTHENTICATE_TO_MY_MAPS,
- MyMapsConstants.SERVICE_NAME);
- // AUTHENTICATE_TO_MY_MAPS callback calls sendToGoogleMaps
- }
-
- private void sendToGoogleMaps(final long trackId, String mapId) {
- SendToMyMaps.OnSendCompletedListener onCompletion = new SendToMyMaps.OnSendCompletedListener() {
- @Override
- public void onSendCompleted(String mapId, boolean success, int statusMessage) {
- sendToMyMapsMessage = getString(statusMessage);
- sendToMyMapsSuccess = success;
- if (sendToMyMapsSuccess) {
- sendToMyMapsMapId = mapId;
- // Update the map id for this track:
- try {
- Track track = providerUtils.getTrack(trackId);
- track.setMapId(mapId);
- providerUtils.updateTrack(track);
- } catch (RuntimeException e) {
- // If that fails whatever reasons we'll just log an error, but
- // continue.
- Log.w(TAG, "Updating map id failed.", e);
- }
- }
-
- onSendToGoogleMapsDone();
- }
- };
- 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);
- }
-
- private void onSendToGoogleMapsDone() {
- SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
- if (sendToGoogleDialog.getSendToFusionTables()) {
- authenticateToFusionTables(null);
- } else if (sendToGoogleDialog.getSendToDocs()) {
- authenticateToGoogleDocs();
- } else {
- onSendToGoogleDone();
- }
- }
-
- private void authenticateToFusionTables(Intent results) {
- if (results == null) { results = new Intent(); }
-
- setProgressValue(0);
- setProgressMessage(R.string.progress_message_authenticating_fusiontables);
- authenticate(results, Constants.AUTHENTICATE_TO_FUSION_TABLES,
- SendToFusionTables.SERVICE_ID);
- // AUTHENTICATE_TO_FUSION_TABLES callback calls sendToFusionTables
- }
-
- private void sendToFusionTables(final long trackId) {
- OnSendCompletedListener onCompletion = new OnSendCompletedListener() {
- @Override
- public void onSendCompleted(String tableId, boolean success,
- int statusMessage) {
- sendToFusionTablesMessage = getString(statusMessage);
- sendToFusionTablesSuccess = success;
- if (sendToFusionTablesSuccess) {
- sendToFusionTablesTableId = tableId;
- // Update the table id for this track:
- try {
- Track track = providerUtils.getTrack(trackId);
- track.setTableId(tableId);
- providerUtils.updateTrack(track);
- } 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();
- }
- };
- sendToTrackId = trackId;
- final SendToFusionTables sender = new SendToFusionTables(this, auth,
- trackId, this/*progressIndicator*/, onCompletion);
-
- HandlerThread handlerThread = new HandlerThread("SendToFusionTables");
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
- handler.post(sender);
- }
-
- private void onSendToFusionTablesDone() {
- SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
- if (sendToGoogleDialog.getSendToDocs()) {
- authenticateToGoogleDocs();
- } else {
- onSendToGoogleDone();
- }
- }
-
- private void authenticateToGoogleDocs() {
- setProgressValue(0);
- setProgressMessage(
- R.string.progress_message_authenticating_docs);
- authenticate(new Intent(),
- Constants.AUTHENTICATE_TO_DOCLIST,
- SendToDocs.GDATA_SERVICE_NAME_DOCLIST);
- // AUTHENTICATE_TO_DOCLIST callback calls authenticateToGoogleTrix
- }
-
- private void authenticateToGoogleTrix() {
- setProgressValue(30);
- setProgressMessage(
- R.string.progress_message_authenticating_docs);
- authenticate(new Intent(),
- Constants.AUTHENTICATE_TO_TRIX,
- SendToDocs.GDATA_SERVICE_NAME_TRIX);
- // AUTHENTICATE_TO_TRIX callback calls sendToGoogleDocs
- }
-
- private void sendToGoogleDocs(final long trackId) {
- Log.d(TAG, "Sending to Docs....");
- setProgressValue(50);
- setProgressMessage(R.string.progress_message_sending_docs);
- final SendToDocs sender = new SendToDocs(this,
- authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
- authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST), trackId);
- sendToTrackId = trackId;
- Runnable onCompletion = new Runnable() {
- public void run() {
- setProgressValue(100);
- dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
- sendToDocsMessage = sender.getStatusMessage();
- sendToDocsSuccess = sender.wasSuccess();
-
- onSendToGoogleDocsDone();
- }
- };
- sender.setOnCompletion(onCompletion);
- sender.run();
- }
-
- private void onSendToGoogleDocsDone() {
- onSendToGoogleDone();
- }
-
- private void onSendToGoogleDone() {
- SendDialog sendToGoogleDialog = dialogManager.getSendToGoogleDialog();
- final boolean sentToMyMaps = sendToGoogleDialog.getSendToMyMaps();
- final boolean sentToFusionTables = sendToGoogleDialog.getSendToFusionTables();
- dialogManager.dismissDialogSafely(DIALOG_PROGRESS);
-
- // We've finished sending the track to the user-selected services. Now
- // we tell them the results of the upload, and optionally share the track.
- // There are a few different paths through this code:
- //
- // 1. The user pre-requested a share (shareRequested == true). We're going
- // to display the result dialog *without* the share button (the share
- // listener will be null). The OK button listener will initiate the
- // share.
- //
- // 2. The user did not pre-request a share, and the set of services to
- // which we succeeded in uploading the track are compatible with
- // sharing. We'll display a share button (the share listener will be
- // non-null), and will share the link if the user clicks it.
- //
- // 3. The user did not pre-request a share, and the set of services to
- // which we succeeded in uploading the track are incompatible with
- // sharing. We won't display a share button.
-
- final boolean canShare = getSendToFusionTablesTableId() != null
- || getSendToMyMapsMapId() != null;
-
- DialogInterface.OnClickListener doShareListener = null;
- if (canShare) {
- doShareListener = new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- shareLinkToMap(sentToMyMaps, sentToFusionTables);
- }
- };
- }
-
- DialogInterface.OnClickListener onOkListener = (canShare && shareRequested)
- ? doShareListener : null;
- DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested)
- ? doShareListener : null;
-
- AlertDialog sendToGoogleResultDialog = ResultDialogFactory.makeDialog(this,
- makeSendToGoogleResults(sendToGoogleDialog), onOkListener, onShareListener);
- DialogManager.showDialogSafely(this, sendToGoogleResultDialog);
- }
-
- boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
- String url = null;
- if (sentToMyMaps && sendToMyMapsSuccess) {
- // Prefer a link to My Maps
- url = MapsFacade.buildMapUrl(sendToMyMapsMapId);
- } else if (sentToFusionTables && sendToFusionTablesSuccess) {
- // Otherwise try using the link to fusion tables
- url = getFusionTablesUrl(sendToTrackId);
- }
-
- if (url != null) {
- shareLinkToMap(url);
- return true;
- }
-
- return false;
- }
-
- protected String getFusionTablesUrl(long trackId) {
- Track track = providerUtils.getTrack(trackId);
- return track == null ? "" : SendToFusionTables.getMapVisualizationUrl(track);
- }
-
- /**
- * Creates a list of {@link SendResult} instances based on the set of
- * services selected in {@link SendDialog} and the results as known to
- * this class.
- */
- private List makeSendToGoogleResults(SendDialog dialog) {
- List results = new ArrayList();
- if (dialog.getSendToMyMaps()) {
- results.add(new SendResult(SendType.MYMAPS, sendToMyMapsSuccess));
- }
- if (dialog.getSendToFusionTables()) {
- results.add(new SendResult(SendType.FUSION_TABLES, sendToFusionTablesSuccess));
- }
- if (dialog.getSendToDocs()) {
- results.add(new SendResult(SendType.DOCS, sendToDocsSuccess));
- }
-
- return results;
- }
-
void clearSelectedTrack() {
dataHub.unloadCurrentTrack();
}
@@ -1221,94 +660,10 @@ public class MyTracks extends TabActivity implements OnTouchListener,
}
}
- /**
- * Saves the track with the given id to the SD card.
- *
- * @param trackId The id of the track to be sent
- */
- public void saveTrack(long trackId, TrackFileFormat format) {
- TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
- WriteProgressController controller = new WriteProgressController(this, writer);
- controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
- @Override
- public void onComplete(TrackWriter writer) {
- dialogManager.showMessageDialog(writer.getErrorMessage(), writer.wasSuccess());
- }
- });
- controller.startWrite();
- }
-
- /**
- * Sends the requested track as an email attachment.
- * This will leave the gpx file on the SD card for at least one hour.
- * Temporary gpx files will be deleted in onStop.
- *
- * @param trackId The id of the track to be sent
- */
- public void sendTrack(long trackId, final TrackFileFormat format) {
- TrackWriter writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
-
- FileUtils fileUtils = new FileUtils();
- String extension = format.getExtension();
- String dirName = fileUtils.buildExternalDirectoryPath(extension, "tmp");
-
- File dir = new File(dirName);
- writer.setDirectory(dir);
-
- WriteProgressController controller = new WriteProgressController(this, writer);
- controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
- @Override
- public void onComplete(TrackWriter writer) {
- if (!writer.wasSuccess()) {
- dialogManager.showMessageDialog(writer.getErrorMessage(), writer.wasSuccess());
- return;
- }
-
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
- shareIntent.putExtra(Intent.EXTRA_SUBJECT,
- getResources().getText(R.string.send_track_subject).toString());
- shareIntent.putExtra(Intent.EXTRA_TEXT,
- getResources().getText(R.string.send_track_body_format)
- .toString());
- shareIntent.setType(format.getMimeType());
- Uri u = Uri.fromFile(new File(writer.getAbsolutePath()));
- shareIntent.putExtra(Intent.EXTRA_STREAM, u);
- startActivity(Intent.createChooser(shareIntent,
- getResources().getText(R.string.share_track).toString()));
- }
- });
-
- controller.startWrite();
- }
-
- public AccountChooser getAccountChooser() {
- return accountChooser;
- }
-
- public ChartActivity getChartActivity() {
- return chartActivity;
- }
-
- public void setChartActivity(ChartActivity chartActivity) {
- this.chartActivity = chartActivity;
- }
-
public DialogManager getDialogManager() {
return dialogManager;
}
- public String getSendToMyMapsMapId() {
- return sendToMyMapsMapId;
- }
-
- public String getSendToFusionTablesTableId() {
- return sendToFusionTablesTableId;
- }
-
- public boolean getSendToGoogleSuccess() {
- return sendToFusionTablesSuccess && sendToDocsSuccess;
- }
-
// @VisibleForTesting
long getRecordingTrackId() {
return sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
@@ -1319,11 +674,6 @@ public class MyTracks extends TabActivity implements OnTouchListener,
return sharedPreferences;
}
- // @VisibleForTesting
- static void clearInstance() {
- instance = null;
- }
-
// @VisibleForTesting
ITrackRecordingService getTrackRecordingService() {
return trackRecordingService;
@@ -1332,4 +682,15 @@ public class MyTracks extends TabActivity implements OnTouchListener,
public TrackDataHub getDataHub() {
return dataHub;
}
+
+ // TODO: Remove very soon
+ private static MyTracks instance;
+
+ public static MyTracks getInstance() {
+ return instance;
+ }
+
+ public static void clearInstance() {
+ instance = null;
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackList.java b/MyTracks/src/com/google/android/apps/mytracks/TrackList.java
index d39fbc032..d75cfbbbd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/TrackList.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/TrackList.java
@@ -16,6 +16,8 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.TracksColumns;
+import com.google.android.apps.mytracks.io.file.SaveActivity;
+import com.google.android.apps.mytracks.io.sendtogoogle.SendActivity;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R;
@@ -138,32 +140,46 @@ public class TrackList extends ListActivity
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
- if (!super.onMenuItemSelected(featureId, item)) {
- switch (item.getItemId()) {
- case Constants.MENU_SHOW: {
- onListItemClick(null, null, 0, trackId);
- return true;
- }
- case Constants.MENU_EDIT: {
- Intent intent = new Intent(this, TrackDetails.class);
- intent.putExtra("trackid", trackId);
- startActivity(intent);
- return true;
- }
- case Constants.MENU_SHARE:
- case Constants.MENU_WRITE_TO_SD_CARD:
- return false;
- default: {
- Intent result = new Intent();
- result.putExtra("trackid", trackId);
- setResult(
- Constants.getActionFromMenuId(item.getItemId()), result);
- finish();
- return true;
- }
+ switch (item.getItemId()) {
+ case Constants.MENU_SHOW: {
+ onListItemClick(null, null, 0, trackId);
+ return true;
+ }
+ case Constants.MENU_EDIT: {
+ Intent intent = new Intent(this, TrackDetails.class);
+ intent.putExtra("trackid", trackId);
+ startActivity(intent);
+ return true;
+ }
+ case Constants.MENU_SHARE:
+ case Constants.MENU_WRITE_TO_SD_CARD:
+ return false;
+ case Constants.MENU_SEND_TO_GOOGLE:
+ SendActivity.sendToGoogle(this, trackId, false);
+ return true;
+ case Constants.MENU_SHARE_LINK:
+ SendActivity.sendToGoogle(this, trackId, true);
+ return true;
+ case Constants.MENU_SAVE_GPX_FILE:
+ case Constants.MENU_SAVE_KML_FILE:
+ case Constants.MENU_SAVE_CSV_FILE:
+ case Constants.MENU_SAVE_TCX_FILE:
+ case Constants.MENU_SHARE_GPX_FILE:
+ case Constants.MENU_SHARE_KML_FILE:
+ case Constants.MENU_SHARE_CSV_FILE:
+ case Constants.MENU_SHARE_TCX_FILE:
+ SaveActivity.handleExportTrackAction(this, trackId,
+ Constants.getActionFromMenuId(item.getItemId()));
+ return true;
+ default: {
+ Intent result = new Intent();
+ result.putExtra("trackid", trackId);
+ setResult(
+ Constants.getActionFromMenuId(item.getItemId()), result);
+ finish();
+ return true;
}
}
- return false;
}
@Override
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/ModernAuthManager.java b/MyTracks/src/com/google/android/apps/mytracks/io/ModernAuthManager.java
index 24c721bc4..8048f4fab 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/ModernAuthManager.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/ModernAuthManager.java
@@ -22,7 +22,6 @@ import com.google.android.accounts.AccountManagerFuture;
import com.google.android.accounts.AuthenticatorException;
import com.google.android.accounts.OperationCanceledException;
import com.google.android.apps.mytracks.AccountChooser;
-import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.Constants;
import android.app.Activity;
@@ -183,7 +182,9 @@ public class ModernAuthManager implements AuthManager {
public void run() {
accountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE,
authToken);
- MyTracks.getInstance().getAccountChooser().chooseAccount(activity,
+
+ AccountChooser accountChooser = new AccountChooser();
+ accountChooser.chooseAccount(activity,
new AccountChooser.AccountHandler() {
@Override
public void handleAccountSelected(Account account) {
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
index 5105285e4..1b0047740 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/SendToDocs.java
@@ -15,8 +15,8 @@
*/
package com.google.android.apps.mytracks.io;
-import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.Constants;
+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.io.docs.DocsHelper;
@@ -25,10 +25,10 @@ import com.google.android.apps.mytracks.io.gdata.GDataWrapper;
import com.google.android.common.gdata.AndroidXmlParserFactory;
import com.google.android.maps.mytracks.R;
import com.google.wireless.gdata.client.GDataClient;
+import com.google.wireless.gdata.client.GDataServiceClient;
import com.google.wireless.gdata.docs.DocumentsClient;
import com.google.wireless.gdata.docs.SpreadsheetsClient;
import com.google.wireless.gdata.docs.XmlDocsGDataParserFactory;
-import com.google.wireless.gdata.client.GDataServiceClient;
import android.app.Activity;
import android.content.SharedPreferences;
@@ -49,11 +49,11 @@ public class SendToDocs {
/** The GData service name for the Google Docs Document List */
public static final String GDATA_SERVICE_NAME_DOCLIST = "writely";
-
+
private final Activity activity;
private final AuthManager trixAuth;
private final AuthManager docListAuth;
- private final long trackId;
+ private final ProgressIndicator progressIndicator;
private final boolean metricUnits;
private final HandlerThread handlerThread;
private final Handler handler;
@@ -64,12 +64,13 @@ public class SendToDocs {
private String statusMessage = "";
private Runnable onCompletion = null;
+
public SendToDocs(Activity activity, AuthManager trixAuth,
- AuthManager docListAuth, long trackId) {
+ AuthManager docListAuth, ProgressIndicator progressIndicator) {
this.activity = activity;
this.trixAuth = trixAuth;
this.docListAuth = docListAuth;
- this.trackId = trackId;
+ this.progressIndicator = progressIndicator;
SharedPreferences preferences = activity.getSharedPreferences(
Constants.SETTINGS_NAME, 0);
@@ -81,23 +82,23 @@ public class SendToDocs {
metricUnits = true;
}
- Log.d(Constants.TAG,
- "Sending to Google Docs: trackId = " + trackId);
handlerThread = new HandlerThread("SendToGoogleDocs");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
- public void run() {
+ public void sendToDocs(final long trackId) {
+ Log.d(Constants.TAG,
+ "Sending to Google Docs: trackId = " + trackId);
handler.post(new Runnable() {
@Override
public void run() {
- doUpload();
+ doUpload(trackId);
}
});
}
- private void doUpload() {
+ private void doUpload(long trackId) {
// TODO
statusMessage = activity.getString(R.string.error_sending_to_fusiontables);
success = false;
@@ -198,7 +199,7 @@ public class SendToDocs {
}
if (spreadsheetId == null) {
- MyTracks.getInstance().setProgressValue(65);
+ progressIndicator.setProgressValue(65);
// Waiting a few seconds and trying again. Maybe the server just had a
// hickup (unfortunately that happens quite a lot...).
try {
@@ -217,7 +218,7 @@ public class SendToDocs {
}
// We were unable to find an existing spreadsheet, so create a new one.
- MyTracks.getInstance().setProgressValue(70);
+ progressIndicator.setProgressValue(70);
if (spreadsheetId == null) {
Log.i(Constants.TAG, "Creating new spreadsheet: " + sheetTitle);
@@ -229,11 +230,11 @@ public class SendToDocs {
+ sheetTitle, e);
return false;
}
- MyTracks.getInstance().setProgressValue(80);
+ progressIndicator.setProgressValue(80);
createdNewSpreadSheet = true;
if (spreadsheetId == null) {
- MyTracks.getInstance().setProgressValue(85);
+ progressIndicator.setProgressValue(85);
// The previous creation might have succeeded even though GData
// reported an error. Seems to be a know bug,
// see http://code.google.com/p/gdata-issues/issues/detail?id=929
@@ -255,7 +256,7 @@ public class SendToDocs {
}
if (spreadsheetId == null) {
- MyTracks.getInstance().setProgressValue(87);
+ progressIndicator.setProgressValue(87);
// Re-try
try {
Thread.sleep(5000);
@@ -290,7 +291,7 @@ public class SendToDocs {
return false;
}
- MyTracks.getInstance().setProgressValue(90);
+ progressIndicator.setProgressValue(90);
docsHelper.addTrackRow(activity, trixAuth, spreadsheetId, worksheetId,
track, metricUnits);
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java
new file mode 100644
index 000000000..f5c9e8688
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java
@@ -0,0 +1,152 @@
+package com.google.android.apps.mytracks.io.file;
+
+import com.google.android.apps.mytracks.Constants;
+import com.google.android.apps.mytracks.DialogManager;
+import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
+import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
+import com.google.android.apps.mytracks.util.FileUtils;
+import com.google.android.maps.mytracks.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+import java.io.File;
+
+public class SaveActivity extends Activity {
+ public static final String EXTRA_TRACK_ID = "track_id";
+ public static final String EXTRA_SHARE_FILE = "share_file";
+ public static final String EXTRA_FILE_FORMAT = "file_format";
+
+ private MyTracksProviderUtils providerUtils;
+ private long trackId;
+ private TrackWriter writer;
+ private boolean shareFile;
+ private TrackFileFormat format;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ providerUtils = MyTracksProviderUtils.Factory.get(this);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ Intent intent = getIntent();
+ trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1);
+ int formatIdx = intent.getIntExtra(EXTRA_FILE_FORMAT, -1);
+ format = TrackFileFormat.values()[formatIdx];
+ shareFile = intent.getBooleanExtra(EXTRA_SHARE_FILE, false);
+
+ writer = TrackWriterFactory.newWriter(this, providerUtils, trackId, format);
+
+ if (shareFile) {
+ // If the file is for sending, save it to a temporary location instead.
+ FileUtils fileUtils = new FileUtils();
+ String extension = format.getExtension();
+ String dirName = fileUtils.buildExternalDirectoryPath(extension, "tmp");
+
+ File dir = new File(dirName);
+ writer.setDirectory(dir);
+ }
+
+ WriteProgressController controller = new WriteProgressController(this, writer);
+ controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
+ @Override
+ public void onComplete() {
+ onWriteComplete();
+ }
+ });
+ controller.startWrite();
+ }
+
+ private void onWriteComplete() {
+ if (shareFile) {
+ shareWrittenFile();
+ } else {
+ showResultDialog();
+ }
+ }
+
+ private void shareWrittenFile() {
+ if (!writer.wasSuccess()) {
+ showResultDialog();
+ return;
+ }
+
+ // Share the file.
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_SUBJECT,
+ getResources().getText(R.string.send_track_subject).toString());
+ shareIntent.putExtra(Intent.EXTRA_TEXT,
+ getResources().getText(R.string.send_track_body_format)
+ .toString());
+ shareIntent.setType(format.getMimeType());
+ Uri u = Uri.fromFile(new File(writer.getAbsolutePath()));
+ shareIntent.putExtra(Intent.EXTRA_STREAM, u);
+ startActivity(Intent.createChooser(shareIntent,
+ getResources().getText(R.string.share_track).toString()));
+ }
+
+ private void showResultDialog() {
+ DialogManager.showMessageDialog(this, writer.getErrorMessage(), writer.wasSuccess(),
+ new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ dialog.dismiss();
+ finish();
+ }
+ });
+ }
+
+ public static void handleExportTrackAction(Context ctx, long trackId, int actionCode) {
+ if (trackId < 0) {
+ return;
+ }
+
+ TrackFileFormat exportFormat = null;
+ switch (actionCode) {
+ case Constants.SAVE_GPX_FILE:
+ case Constants.SHARE_GPX_FILE:
+ exportFormat = TrackFileFormat.GPX;
+ break;
+ case Constants.SAVE_KML_FILE:
+ case Constants.SHARE_KML_FILE:
+ exportFormat = TrackFileFormat.KML;
+ break;
+ case Constants.SAVE_CSV_FILE:
+ case Constants.SHARE_CSV_FILE:
+ exportFormat = TrackFileFormat.CSV;
+ break;
+ case Constants.SAVE_TCX_FILE:
+ case Constants.SHARE_TCX_FILE:
+ exportFormat = TrackFileFormat.TCX;
+ break;
+ default:
+ throw new IllegalArgumentException("Warning unhandled action code: " + actionCode);
+ }
+
+ boolean shareFile = false;
+ switch (actionCode) {
+ case Constants.SHARE_GPX_FILE:
+ case Constants.SHARE_KML_FILE:
+ case Constants.SHARE_CSV_FILE:
+ case Constants.SHARE_TCX_FILE:
+ shareFile = true;
+ }
+
+ Intent intent = new Intent(ctx, SaveActivity.class);
+ intent.putExtra(EXTRA_TRACK_ID, trackId);
+ intent.putExtra(EXTRA_FILE_FORMAT, exportFormat.ordinal());
+ intent.putExtra(EXTRA_SHARE_FILE, shareFile);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+ ctx.startActivity(intent);
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/WriteProgressController.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/WriteProgressController.java
similarity index 95%
rename from MyTracks/src/com/google/android/apps/mytracks/WriteProgressController.java
rename to MyTracks/src/com/google/android/apps/mytracks/io/file/WriteProgressController.java
index 3f0356756..861df8ddd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/WriteProgressController.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/WriteProgressController.java
@@ -13,9 +13,9 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.google.android.apps.mytracks;
+package com.google.android.apps.mytracks.io.file;
-import com.google.android.apps.mytracks.io.file.TrackWriter;
+import com.google.android.apps.mytracks.DialogManager;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -41,7 +41,7 @@ class WriteProgressController {
* dialog has been dismissed. Whether the write succeeded can be
* determined by examining the {@link TrackWriter}.
*/
- public void onComplete(TrackWriter writer);
+ public void onComplete();
}
private final Activity activity;
@@ -104,7 +104,7 @@ class WriteProgressController {
DialogManager.dismissDialogSafely(activity, dialog);
if (onCompletionListener != null) {
- onCompletionListener.onComplete(writer);
+ onCompletionListener.onComplete();
}
}
};
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java
new file mode 100644
index 000000000..cda4ec755
--- /dev/null
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendActivity.java
@@ -0,0 +1,619 @@
+package com.google.android.apps.mytracks.io.sendtogoogle;
+
+import static com.google.android.apps.mytracks.Constants.TAG;
+
+import com.google.android.accounts.Account;
+import com.google.android.apps.mytracks.AccountChooser;
+import com.google.android.apps.mytracks.Constants;
+import com.google.android.apps.mytracks.DialogManager;
+import com.google.android.apps.mytracks.MyMapsList;
+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.io.AuthManager;
+import com.google.android.apps.mytracks.io.AuthManagerFactory;
+import com.google.android.apps.mytracks.io.SendToDocs;
+import com.google.android.apps.mytracks.io.SendToFusionTables;
+import com.google.android.apps.mytracks.io.SendToFusionTables.OnSendCompletedListener;
+import com.google.android.apps.mytracks.io.SendToMyMaps;
+import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
+import com.google.android.apps.mytracks.io.mymaps.MyMapsConstants;
+import com.google.android.maps.mytracks.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Helper for managing the sending of tracks to Google services.
+ *
+ * @author Rodrigo Damazio
+ */
+public class SendActivity extends Activity implements ProgressIndicator {
+ public static final String EXTRA_SHARE_LINK = "share_link";
+ public static final String EXTRA_TRACK_ID = "track_id";
+
+ // Services
+ private MyTracksProviderUtils providerUtils;
+ private SharedPreferences sharedPreferences;
+
+ // Authentication
+ private AuthManager lastAuth;
+ private final HashMap authMap =
+ new HashMap();
+ private final AccountChooser accountChooser = new AccountChooser();
+
+ // Send request information.
+ private boolean shareRequested = false;
+ private long sendTrackId;
+
+ // Send result information, used by SendToGoogleResultDialog.
+ private boolean sendToMyMapsSuccess = false;
+ private boolean sendToFusionTablesSuccess = false;
+ private boolean sendToDocsSuccess = false;
+ private String sendToMyMapsMapId;
+ private String sendToFusionTablesTableId;
+
+ // TODO: Make these be used for showing results
+ @SuppressWarnings("unused")
+ private String sendToMyMapsMessage;
+ @SuppressWarnings("unused")
+ private String sendToFusionTablesMessage;
+ @SuppressWarnings("unused")
+ private String sendToDocsMessage;
+
+ // State used while sending.
+ private SendDialog sendDialog;
+ private ProgressDialog progressDialog;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ providerUtils = MyTracksProviderUtils.Factory.get(this);
+ sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, 0);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ resetState();
+
+ sendTrackId = getIntent().getLongExtra(EXTRA_TRACK_ID, -1);
+
+ sendDialog = new SendDialog(this);
+ sendDialog.setOwnerActivity(this);
+ sendDialog.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface arg0, int which) {
+ if (which != DialogInterface.BUTTON_POSITIVE) {
+ finish();
+ return;
+ }
+
+ doSend();
+ }
+ });
+ sendDialog.show();
+ }
+
+ /**
+ * 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.
+ */
+ private void doSend() {
+ progressDialog = new ProgressDialog(this);
+ progressDialog.setIcon(android.R.drawable.ic_dialog_info);
+ progressDialog.setTitle(R.string.progress_title);
+ progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ progressDialog.setMessage("");
+ progressDialog.setMax(100);
+ progressDialog.setProgress(0);
+ progressDialog.show();
+
+ if (sendDialog.getSendToMyMaps()) {
+ sendToGoogleMapsOrPickMap();
+ } else if (sendDialog.getSendToFusionTables()) {
+ authenticateToFusionTables(null);
+ } else if (sendDialog.getSendToDocs()) {
+ authenticateToGoogleDocs();
+ } else {
+ Log.w(TAG, "Nowhere to upload to");
+ onSendToGoogleDone();
+ }
+ }
+
+ private void sendToGoogleMapsOrPickMap() {
+ if (!sendDialog.getCreateNewMap()) {
+ // Ask the user to choose a map to upload into
+ Intent listIntent = new Intent(this, MyMapsList.class);
+ startActivityForResult(listIntent, Constants.GET_MAP);
+ // The callback for GET_MAP calls authenticateToGoogleMaps
+ } else {
+ authenticateToGoogleMaps(null);
+ }
+ }
+
+ private void authenticateToGoogleMaps(Intent results) {
+ if (results == null) { results = new Intent(); }
+
+ progressDialog.setProgress(0);
+ progressDialog.setMessage(getString(
+ R.string.progress_message_authenticating_mymaps));
+ authenticate(results, Constants.AUTHENTICATE_TO_MY_MAPS,
+ MyMapsConstants.SERVICE_NAME);
+ // AUTHENTICATE_TO_MY_MAPS callback calls sendToGoogleMaps
+ }
+
+ private void sendToGoogleMaps(String mapId) {
+ SendToMyMaps.OnSendCompletedListener onCompletion = new SendToMyMaps.OnSendCompletedListener() {
+ @Override
+ public void onSendCompleted(String mapId, boolean success, int statusMessage) {
+ // TODO: Use this message
+ sendToMyMapsMessage = getString(statusMessage);
+ sendToMyMapsSuccess = success;
+ if (sendToMyMapsSuccess) {
+ sendToMyMapsMapId = mapId;
+ // Update the map id for this track:
+ try {
+ Track track = providerUtils.getTrack(sendTrackId);
+ track.setMapId(mapId);
+ providerUtils.updateTrack(track);
+ } catch (RuntimeException e) {
+ // If that fails whatever reasons we'll just log an error, but
+ // continue.
+ Log.w(TAG, "Updating map id failed.", e);
+ }
+ }
+
+ onSendToGoogleMapsDone();
+ }
+ };
+ final SendToMyMaps sender = new SendToMyMaps(this, mapId, lastAuth,
+ sendTrackId, this /*progressIndicator*/, onCompletion);
+
+ HandlerThread handlerThread = new HandlerThread("SendToMyMaps");
+ handlerThread.start();
+ Handler handler = new Handler(handlerThread.getLooper());
+ handler.post(sender);
+ }
+
+ private void onSendToGoogleMapsDone() {
+ if (sendDialog.getSendToFusionTables()) {
+ authenticateToFusionTables(null);
+ } else if (sendDialog.getSendToDocs()) {
+ authenticateToGoogleDocs();
+ } else {
+ onSendToGoogleDone();
+ }
+ }
+
+ private void authenticateToFusionTables(Intent results) {
+ if (results == null) { results = new Intent(); }
+
+ progressDialog.setProgress(0);
+ progressDialog.setMessage(getString(
+ R.string.progress_message_authenticating_fusiontables));
+ authenticate(results, Constants.AUTHENTICATE_TO_FUSION_TABLES,
+ SendToFusionTables.SERVICE_ID);
+ // AUTHENTICATE_TO_FUSION_TABLES callback calls sendToFusionTables
+ }
+
+ private void sendToFusionTables() {
+ OnSendCompletedListener onCompletion = new OnSendCompletedListener() {
+ @Override
+ public void onSendCompleted(String tableId, boolean success,
+ int statusMessage) {
+ // TODO: Use this message
+ sendToFusionTablesMessage = getString(statusMessage);
+ sendToFusionTablesSuccess = success;
+ if (sendToFusionTablesSuccess) {
+ sendToFusionTablesTableId = tableId;
+ // Update the table id for this track:
+ try {
+ Track track = providerUtils.getTrack(sendTrackId);
+ track.setTableId(tableId);
+ providerUtils.updateTrack(track);
+ } 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();
+ }
+ };
+ final SendToFusionTables sender = new SendToFusionTables(this, lastAuth,
+ sendTrackId, this/*progressIndicator*/, onCompletion);
+
+ HandlerThread handlerThread = new HandlerThread("SendToFusionTables");
+ handlerThread.start();
+ Handler handler = new Handler(handlerThread.getLooper());
+ handler.post(sender);
+ }
+
+ private void onSendToFusionTablesDone() {
+ if (sendDialog.getSendToDocs()) {
+ authenticateToGoogleDocs();
+ } else {
+ onSendToGoogleDone();
+ }
+ }
+
+ private void authenticateToGoogleDocs() {
+ setProgressValue(0);
+ setProgressMessage(
+ R.string.progress_message_authenticating_docs);
+ authenticate(new Intent(),
+ Constants.AUTHENTICATE_TO_DOCLIST,
+ SendToDocs.GDATA_SERVICE_NAME_DOCLIST);
+ // AUTHENTICATE_TO_DOCLIST callback calls authenticateToGoogleTrix
+ }
+
+ private void authenticateToGoogleTrix() {
+ setProgressValue(30);
+ setProgressMessage(
+ R.string.progress_message_authenticating_docs);
+ authenticate(new Intent(),
+ Constants.AUTHENTICATE_TO_TRIX,
+ SendToDocs.GDATA_SERVICE_NAME_TRIX);
+ // AUTHENTICATE_TO_TRIX callback calls sendToGoogleDocs
+ }
+
+ private void sendToGoogleDocs() {
+ Log.d(TAG, "Sending to Docs....");
+ setProgressValue(50);
+ setProgressMessage(R.string.progress_message_sending_docs);
+ final SendToDocs sender = new SendToDocs(this,
+ authMap.get(SendToDocs.GDATA_SERVICE_NAME_TRIX),
+ authMap.get(SendToDocs.GDATA_SERVICE_NAME_DOCLIST),
+ this);
+ Runnable onCompletion = new Runnable() {
+ public void run() {
+ setProgressValue(100);
+
+ // TODO: Use this message
+ sendToDocsMessage = sender.getStatusMessage();
+ sendToDocsSuccess = sender.wasSuccess();
+
+ onSendToGoogleDocsDone();
+ }
+ };
+ sender.setOnCompletion(onCompletion);
+ sender.sendToDocs(sendTrackId);
+ }
+
+ private void onSendToGoogleDocsDone() {
+ onSendToGoogleDone();
+ }
+
+ private void onSendToGoogleDone() {
+ final boolean sentToMyMaps = sendDialog.getSendToMyMaps();
+ final boolean sentToFusionTables = sendDialog.getSendToFusionTables();
+ List results = makeSendToGoogleResults();
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ progressDialog.dismiss();
+ progressDialog = null;
+ sendDialog = null;
+ }
+ });
+
+ // We've finished sending the track to the user-selected services. Now
+ // we tell them the results of the upload, and optionally share the track.
+ // There are a few different paths through this code:
+ //
+ // 1. The user pre-requested a share (shareRequested == true). We're going
+ // to display the result dialog *without* the share button (the share
+ // listener will be null). The OK button listener will initiate the
+ // share.
+ //
+ // 2. The user did not pre-request a share, and the set of services to
+ // which we succeeded in uploading the track are compatible with
+ // sharing. We'll display a share button (the share listener will be
+ // non-null), and will share the link if the user clicks it.
+ //
+ // 3. The user did not pre-request a share, and the set of services to
+ // which we succeeded in uploading the track are incompatible with
+ // sharing. We won't display a share button.
+
+ final boolean canShare = sendToFusionTablesTableId != null
+ || sendToMyMapsMapId != null;
+
+ DialogInterface.OnClickListener doShareListener = null;
+ if (canShare) {
+ doShareListener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ shareLinkToMap(sentToMyMaps, sentToFusionTables);
+ }
+ };
+ }
+
+ DialogInterface.OnClickListener onOkListener = (canShare && shareRequested)
+ ? doShareListener : null;
+ DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested)
+ ? doShareListener : null;
+
+ AlertDialog sendToGoogleResultDialog = ResultDialogFactory.makeDialog(this,
+ results, onOkListener, onShareListener);
+ DialogManager.showDialogSafely(this, sendToGoogleResultDialog);
+ }
+
+ boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
+ String url = null;
+ if (sentToMyMaps && sendToMyMapsSuccess) {
+ // Prefer a link to My Maps
+ url = MapsFacade.buildMapUrl(sendToMyMapsMapId);
+ } else if (sentToFusionTables && sendToFusionTablesSuccess) {
+ // Otherwise try using the link to fusion tables
+ url = getFusionTablesUrl(sendTrackId);
+ }
+
+ if (url != null) {
+ shareLinkToMap(url);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Shares a link to a My Map or Fusion Table via external app (email, gmail, ...)
+ * A chooser with apps that support text/plain will be shown to the user.
+ */
+ private void shareLinkToMap(String url) {
+ boolean shareUrlOnly = sharedPreferences.getBoolean(
+ getString(R.string.share_url_only_key), false);
+ String msg = shareUrlOnly ? url : String.format(
+ getResources().getText(R.string.share_map_body_format).toString(), url);
+
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.setType("text/plain");
+ shareIntent.putExtra(Intent.EXTRA_SUBJECT,
+ getResources().getText(R.string.share_map_subject).toString());
+ shareIntent.putExtra(Intent.EXTRA_TEXT, msg);
+ startActivity(Intent.createChooser(shareIntent,
+ getResources().getText(R.string.share_map).toString()));
+ }
+
+ protected String getFusionTablesUrl(long trackId) {
+ Track track = providerUtils.getTrack(trackId);
+ return track == null ? "" : SendToFusionTables.getMapVisualizationUrl(track);
+ }
+
+ /**
+ * Creates a list of {@link SendResult} instances based on the set of
+ * services selected in {@link SendDialog} and the results as known to
+ * this class.
+ */
+ private List makeSendToGoogleResults() {
+ List results = new ArrayList();
+ if (sendDialog.getSendToMyMaps()) {
+ results.add(new SendResult(SendType.MYMAPS, sendToMyMapsSuccess));
+ }
+ if (sendDialog.getSendToFusionTables()) {
+ results.add(new SendResult(SendType.FUSION_TABLES, sendToFusionTablesSuccess));
+ }
+ if (sendDialog.getSendToDocs()) {
+ results.add(new SendResult(SendType.DOCS, sendToDocsSuccess));
+ }
+
+ return results;
+ }
+
+ /**
+ * Initializes the authentication manager which obtains an authentication
+ * token, prompting the user for a login and password if needed.
+ */
+ private void authenticate(final Intent results, final int requestCode,
+ final String service) {
+ lastAuth = authMap.get(service);
+ if (lastAuth == null) {
+ Log.i(TAG, "Creating a new authentication for service: " + service);
+ lastAuth = AuthManagerFactory.getAuthManager(this,
+ Constants.GET_LOGIN,
+ null,
+ true,
+ service);
+ authMap.put(service, lastAuth);
+ }
+
+ Log.d(TAG, "Logging in to " + service + "...");
+ if (AuthManagerFactory.useModernAuthManager()) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ chooseAccount(results, requestCode, service);
+ }
+ });
+ } else {
+ doLogin(results, requestCode, service, null);
+ }
+ }
+
+ private void chooseAccount(final Intent results, final int requestCode,
+ final String service) {
+ accountChooser.chooseAccount(SendActivity.this,
+ new AccountChooser.AccountHandler() {
+ @Override
+ public void handleAccountSelected(Account account) {
+ if (account == null) {
+ progressDialog.dismiss();
+ return;
+ }
+
+ doLogin(results, requestCode, service, account);
+ }
+ });
+ }
+
+ private void doLogin(final Intent results, final int requestCode,
+ final String service, final Account account) {
+ lastAuth.doLogin(new Runnable() {
+ public void run() {
+ Log.i(TAG, "Loggin success for " + service + "!");
+ onActivityResult(requestCode, RESULT_OK, results);
+ }
+ }, account);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode,
+ final Intent results) {
+ switch (requestCode) {
+ case Constants.GET_LOGIN: {
+ // TODO: This is a result from inside the auth manager,
+ // make this return path explicit.
+ if (resultCode != RESULT_OK || lastAuth == null ||
+ !lastAuth.authResult(resultCode, results)) {
+ progressDialog.dismiss();
+ }
+ break;
+ }
+ case Constants.GET_MAP: {
+ // User picked a map to upload to
+ if (resultCode == RESULT_OK) {
+ results.putExtra("trackid", sendTrackId);
+ if (results.hasExtra("mapid")) {
+ sendToMyMapsMapId = results.getStringExtra("mapid");
+ }
+ authenticateToGoogleMaps(results);
+ } else {
+ onSendToGoogleDone();
+ }
+ break;
+ }
+ case Constants.AUTHENTICATE_TO_MY_MAPS: {
+ // Authenticated with Google My Maps
+ if (results != null && resultCode == RESULT_OK) {
+ final String mapId;
+ if (results.hasExtra("mapid")) {
+ mapId = results.getStringExtra("mapid");
+ } else {
+ mapId = "new";
+ }
+
+ sendToGoogleMaps(mapId);
+ } else {
+ onSendToGoogleDone();
+ }
+ break;
+ }
+ case Constants.AUTHENTICATE_TO_FUSION_TABLES: {
+ // Authenticated with Google Fusion Tables
+ if (results != null && resultCode == RESULT_OK) {
+ sendToFusionTables();
+ } else {
+ onSendToGoogleDone();
+ }
+ break;
+ }
+ case Constants.AUTHENTICATE_TO_DOCLIST: {
+ // Authenticated with Google Docs
+ if (resultCode == RESULT_OK) {
+ authenticateToGoogleTrix();
+ } else {
+ onSendToGoogleDone();
+ }
+ break;
+ }
+ case Constants.AUTHENTICATE_TO_TRIX: {
+ // Authenticated with Trix
+ if (resultCode == RESULT_OK) {
+ sendToGoogleDocs();
+ } else {
+ onSendToGoogleDone();
+ }
+ break;
+ }
+ case Constants.SHARE_LINK: {
+ Track selectedTrack = providerUtils.getTrack(sendTrackId);
+ if (selectedTrack != null) {
+ if (!TextUtils.isEmpty(selectedTrack.getMapId())) {
+ shareLinkToMap(MapsFacade.buildMapUrl(selectedTrack.getMapId()));
+ } else if (!TextUtils.isEmpty(selectedTrack.getTableId())) {
+ shareLinkToMap(getFusionTablesUrl(sendTrackId));
+ } else {
+ shareRequested = true;
+ sendDialog.dismiss();
+ }
+ }
+ break;
+ }
+
+ default: {
+ Log.w(TAG, "Warning unhandled request code: " + requestCode);
+ }
+ }
+ }
+
+ /**
+ * Resets status information for sending to MyMaps/Docs.
+ */
+ private void resetState() {
+ sendToMyMapsMapId = null;
+ sendToMyMapsMessage = "";
+ sendToMyMapsSuccess = true;
+ sendToFusionTablesMessage = "";
+ sendToFusionTablesSuccess = true;
+ sendToDocsMessage = "";
+ sendToDocsSuccess = true;
+ sendToFusionTablesTableId = null;
+ }
+
+ @Override
+ public void setProgressMessage(final int resId) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ if (progressDialog != null) {
+ progressDialog.setMessage(getString(resId));
+ }
+ }
+ });
+ }
+
+ @Override
+ public void setProgressValue(final int percent) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ if (progressDialog != null) {
+ progressDialog.setProgress(percent);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void clearProgressMessage() {
+ progressDialog.setMessage("");
+ }
+
+ public static void sendToGoogle(Context ctx, long trackId, boolean shareLink) {
+ Intent intent = new Intent(ctx, SendActivity.class);
+ intent.putExtra(SendActivity.EXTRA_TRACK_ID, trackId);
+ intent.putExtra(SendActivity.EXTRA_SHARE_LINK, shareLink);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+ ctx.startActivity(intent);
+ }
+}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendDialog.java b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendDialog.java
index 16df9c5e3..868e25ed1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendDialog.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/io/sendtogoogle/SendDialog.java
@@ -16,8 +16,6 @@
package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.Constants;
-import com.google.android.apps.mytracks.DialogManager;
-import com.google.android.apps.mytracks.MyTracks;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
@@ -42,15 +40,13 @@ import android.widget.RadioGroup;
*/
public class SendDialog extends Dialog {
- private RadioGroup groupMyMaps;
private RadioButton createNewMapRadioButton;
private RadioButton pickMapRadioButton;
private CheckBox sendToMyMapsCheckBox;
private CheckBox sendToFusionTablesCheckBox;
private CheckBox sendToDocsCheckBox;
- private RadioButton sendStatsRadioButton;
private RadioButton sendStatsAndPointsRadioButton;
- private Button sendButton;
+ private OnClickListener clickListener;
public SendDialog(Context context) {
super(context);
@@ -62,18 +58,38 @@ public class SendDialog extends Dialog {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mytracks_send_to_google);
+ final Button sendButton = (Button) findViewById(R.id.sendtogoogle_send_now);
+ final RadioGroup groupMyMaps = (RadioGroup) findViewById(R.id.sendtogoogle_group_mymaps);
+ sendToMyMapsCheckBox =
+ (CheckBox) findViewById(R.id.sendtogoogle_google_mymaps);
+ sendToFusionTablesCheckBox =
+ (CheckBox) findViewById(R.id.sendtogoogle_google_fusiontables);
+ sendToDocsCheckBox = (CheckBox) findViewById(R.id.sendtogoogle_google_docs);
+ createNewMapRadioButton =
+ (RadioButton) findViewById(R.id.sendtogoogle_create_new_map);
+ pickMapRadioButton =
+ (RadioButton) findViewById(R.id.sendtogoogle_pick_existing_map);
+ RadioButton sendStatsRadioButton = (RadioButton) findViewById(R.id.sendtogoogle_send_stats);
+ sendStatsAndPointsRadioButton = (RadioButton) findViewById(
+ R.id.sendtogoogle_send_stats_and_points);
+
Button cancel = (Button) findViewById(R.id.sendtogoogle_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- MyTracks.getInstance().dismissDialog(DialogManager.DIALOG_SEND_TO_GOOGLE);
+ if (clickListener != null) {
+ clickListener.onClick(SendDialog.this, BUTTON_NEGATIVE);
+ }
+ dismiss();
}
});
Button send = (Button) findViewById(R.id.sendtogoogle_send_now);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
+ if (clickListener != null) {
+ clickListener.onClick(SendDialog.this, BUTTON_POSITIVE);
+ }
dismiss();
- MyTracks.getInstance().sendToGoogle();
}
});
@@ -86,25 +102,9 @@ public class SendDialog extends Dialog {
groupMyMaps.setVisibility(sendToMyMapsCheckBox.isChecked() ? View.VISIBLE : View.INVISIBLE);
}
};
-
- sendButton = (Button) findViewById(R.id.sendtogoogle_send_now);
- groupMyMaps = (RadioGroup) findViewById(R.id.sendtogoogle_group_mymaps);
- sendToMyMapsCheckBox =
- (CheckBox) findViewById(R.id.sendtogoogle_google_mymaps);
sendToMyMapsCheckBox.setOnCheckedChangeListener(checkBoxListener);
- sendToFusionTablesCheckBox =
- (CheckBox) findViewById(R.id.sendtogoogle_google_fusiontables);
sendToFusionTablesCheckBox.setOnCheckedChangeListener(checkBoxListener);
- sendToDocsCheckBox = (CheckBox) findViewById(R.id.sendtogoogle_google_docs);
sendToDocsCheckBox.setOnCheckedChangeListener(checkBoxListener);
- createNewMapRadioButton =
- (RadioButton) findViewById(R.id.sendtogoogle_create_new_map);
- pickMapRadioButton =
- (RadioButton) findViewById(R.id.sendtogoogle_pick_existing_map);
- sendStatsRadioButton =
- (RadioButton) findViewById(R.id.sendtogoogle_send_stats);
- sendStatsAndPointsRadioButton = (RadioButton) findViewById(
- R.id.sendtogoogle_send_stats_and_points);
SharedPreferences prefs =
getContext().getSharedPreferences(Constants.SETTINGS_NAME, 0);
@@ -163,6 +163,10 @@ public class SendDialog extends Dialog {
super.onStop();
}
+ public void setOnClickListener(OnClickListener clickListener) {
+ this.clickListener = clickListener;
+ }
+
public boolean getSendToMyMaps() {
return sendToMyMapsCheckBox.isChecked();
}
@@ -182,4 +186,4 @@ public class SendDialog extends Dialog {
public boolean getSendStatsAndPoints() {
return sendStatsAndPointsRadioButton.isChecked();
}
-}
+}
\ No newline at end of file
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/DialogManagerTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/DialogManagerTest.java
index 1b23a0315..5a50fc677 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/DialogManagerTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/DialogManagerTest.java
@@ -38,13 +38,6 @@ public class DialogManagerTest
assertNull(MyTracks.getInstance());
}
- public void test_onCreateChartSettings() {
- Dialog d =
- getActivity().onCreateDialog(DialogManager.DIALOG_CHART_SETTINGS, null);
- assertNotNull(d);
- assertTrue(d instanceof ChartSettingsDialog);
- }
-
public void test_onCreateImportProgress() {
Dialog d =
getActivity().onCreateDialog(
@@ -62,11 +55,4 @@ public class DialogManagerTest
assertEquals(100, pd.getMax());
assertEquals(10, pd.getProgress());
}
-
- public void test_onCreateSendToGoogle() {
- Dialog d =
- getActivity().onCreateDialog(DialogManager.DIALOG_SEND_TO_GOOGLE, null);
- assertNotNull(d);
- assertTrue(d instanceof SendDialog);
- }
}
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/WriteProgressControllerTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/WriteProgressControllerTest.java
similarity index 92%
rename from MyTracksTest/src/com/google/android/apps/mytracks/WriteProgressControllerTest.java
rename to MyTracksTest/src/com/google/android/apps/mytracks/io/file/WriteProgressControllerTest.java
index 2f4349b32..19d251281 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/WriteProgressControllerTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/io/file/WriteProgressControllerTest.java
@@ -13,10 +13,11 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.google.android.apps.mytracks;
+package com.google.android.apps.mytracks.io.file;
-import com.google.android.apps.mytracks.io.file.MockTrackWriter;
+import com.google.android.apps.mytracks.MyTracks;
import com.google.android.apps.mytracks.io.file.TrackWriter;
+import com.google.android.apps.mytracks.io.file.WriteProgressController;
import android.app.ProgressDialog;
import android.test.ActivityInstrumentationTestCase2;
@@ -60,7 +61,7 @@ public class WriteProgressControllerTest extends ActivityInstrumentationTestCase
getActivity(), mockWriter);
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
@Override
- public void onComplete(TrackWriter writer) {
+ public void onComplete() {
controllerDoneRef.set(true);
}
});