Moving back to managed dialogs to make them still work cross-activity.

This commit is contained in:
Rodrigo Damazio
2011-06-28 05:58:54 -03:00
parent 565662a8aa
commit abd8a230b4
11 changed files with 298 additions and 169 deletions
@@ -35,6 +35,7 @@ import com.google.android.apps.mytracks.util.UnitConversions;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.location.Location; import android.location.Location;
@@ -60,6 +61,7 @@ import java.util.EnumSet;
*/ */
public class ChartActivity extends Activity implements TrackDataListener { public class ChartActivity extends Activity implements TrackDataListener {
private static final int CHART_SETTINGS_DIALOG = 1;
private final DoubleBuffer elevationBuffer = private final DoubleBuffer elevationBuffer =
new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR); new DoubleBuffer(Constants.ELEVATION_SMOOTHING_FACTOR);
private final DoubleBuffer speedBuffer = private final DoubleBuffer speedBuffer =
@@ -203,34 +205,49 @@ public class ChartActivity extends Activity implements TrackDataListener {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case Constants.MENU_CHART_SETTINGS: case Constants.MENU_CHART_SETTINGS:
showSettingsDialog(); showDialog(CHART_SETTINGS_DIALOG);
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void showSettingsDialog() { @Override
final ChartSettingsDialog settingsDialog = new ChartSettingsDialog(this); protected Dialog onCreateDialog(int id) {
settingsDialog.setOwnerActivity(this); if (id == CHART_SETTINGS_DIALOG) {
final ChartSettingsDialog settingsDialog = new ChartSettingsDialog(this);
settingsDialog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) return;
for (int i = 0; i < ChartView.NUM_SERIES; i++) {
boolean seriesEnabled = settingsDialog.isSeriesEnabled(i);
chartView.getChartValueSeries(i).setEnabled(seriesEnabled);
}
setMode(settingsDialog.getMode());
chartView.postInvalidate();
}
});
return settingsDialog;
}
return super.onCreateDialog(id);
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if (id == CHART_SETTINGS_DIALOG) {
prepareSettingsDialog((ChartSettingsDialog) dialog);
}
}
private void prepareSettingsDialog(final ChartSettingsDialog settingsDialog) {
settingsDialog.setMode(mode); settingsDialog.setMode(mode);
for (int i = 0; i < ChartView.NUM_SERIES; i++) { for (int i = 0; i < ChartView.NUM_SERIES; i++) {
settingsDialog.setSeriesEnabled(i, chartView.getChartValueSeries(i).isEnabled()); settingsDialog.setSeriesEnabled(i, chartView.getChartValueSeries(i).isEnabled());
} }
settingsDialog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) return;
for (int i = 0; i < ChartView.NUM_SERIES; i++) {
chartView.getChartValueSeries(i).setEnabled(settingsDialog.isSeriesEnabled(i));
}
setMode(settingsDialog.getMode());
}
});
settingsDialog.show();
} }
/** /**
@@ -1,12 +1,12 @@
/* /*
* Copyright 2009 Google Inc. * Copyright 2009 Google Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * 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 * use this file except in compliance with the License. You may obtain a copy of
* the License at * the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -97,7 +97,7 @@ public class ChartSettingsDialog extends Dialog {
public Mode getMode() { public Mode getMode() {
if (distance == null) return Mode.BY_DISTANCE; if (distance == null) return Mode.BY_DISTANCE;
return distance.isSelected() ? Mode.BY_DISTANCE : Mode.BY_TIME; return distance.isChecked() ? Mode.BY_DISTANCE : Mode.BY_TIME;
} }
public boolean isSeriesEnabled(int seriesIdx) { public boolean isSeriesEnabled(int seriesIdx) {
@@ -17,12 +17,8 @@ package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.TAG; import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface;
import android.util.Log; import android.util.Log;
import android.view.WindowManager.BadTokenException; import android.view.WindowManager.BadTokenException;
@@ -33,24 +29,6 @@ import android.view.WindowManager.BadTokenException;
*/ */
public class DialogManager { public class DialogManager {
public static void showMessageDialog(
Activity ctx, int message, boolean success, DialogInterface.OnClickListener okListener) {
if (ctx.isFinishing()) {
Log.w(TAG, "Activity finishing - not showing dialog");
return;
}
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();
}
/** /**
* The equivalent of {@link #showDialogSafely(int)}, but for a specific * The equivalent of {@link #showDialogSafely(int)}, but for a specific
* dialog instance. * dialog instance.
@@ -100,7 +100,6 @@ public class SendToMyMaps implements Runnable {
int statusMessageId = R.string.error_sending_to_mymap; int statusMessageId = R.string.error_sending_to_mymap;
boolean success = true; boolean success = true;
try { try {
progressIndicator.setProgressValue(1);
progressIndicator.setProgressMessage( progressIndicator.setProgressMessage(
R.string.progress_message_reading_track); R.string.progress_message_reading_track);
@@ -454,9 +453,10 @@ public class SendToMyMaps implements Runnable {
// The percent of the total that represents the completed part of this // The percent of the total that represents the completed part of this
// segment. // segment.
int totalPercentage = int totalPercentage =
(totalLocationsRead + totalLocationsPrepared + totalLocationsUploaded) (totalLocationsRead + totalLocationsPrepared + totalLocationsUploaded) * 100
/ (totalLocations * 3); / (totalLocations * 3);
totalPercentage = Math.min(99, totalPercentage); totalPercentage = Math.min(99, totalPercentage);
Log.d(TAG, "Percentage: read=" + totalLocationsRead + "; prep=" + totalLocationsPrepared + "; up=" + totalLocationsUploaded + "; total=" + totalLocations + "; percentage=" + totalPercentage);
progressIndicator.setProgressValue(totalPercentage); progressIndicator.setProgressValue(totalPercentage);
} }
} }
@@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.io.file;
import static com.google.android.apps.mytracks.Constants.TAG; import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.DialogManager;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.util.UriUtils; import com.google.android.apps.mytracks.util.UriUtils;
@@ -26,6 +25,7 @@ import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -50,9 +50,16 @@ import org.xml.sax.SAXException;
*/ */
public class ImportActivity extends Activity { public class ImportActivity extends Activity {
private ProgressDialog progressDialog; private static final int PROGRESS_DIALOG = 1;
private static final int SUCCESS_DIALOG = 2;
private static final int FAILURE_DIALOG = 3;
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
private ProgressDialog progressDialog;
private int resultMessage;
private long importedTrackIds[];
@Override @Override
public void onCreate(Bundle savedState) { public void onCreate(Bundle savedState) {
super.onCreate(savedState); super.onCreate(savedState);
@@ -78,49 +85,114 @@ public class ImportActivity extends Activity {
startTrackImport(data.getPath()); startTrackImport(data.getPath());
} }
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(this);
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
progressDialog.setTitle(R.string.progress_title);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(getString(R.string.import_progress_message));
return progressDialog;
case SUCCESS_DIALOG:
final Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setCancelable(true);
dialogBuilder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
dialogBuilder.setNeutralButton(R.string.import_show_track, new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
showImportedTrack();
finish();
}
});
return dialogBuilder.create();
case FAILURE_DIALOG:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setNeutralButton(R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.error);
return builder.create();
}
return null;
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
switch (id) {
case SUCCESS_DIALOG:
AlertDialog successDialog = (AlertDialog) dialog;
successDialog.setMessage(getString(R.string.import_success, importedTrackIds.length));
break;
case FAILURE_DIALOG:
AlertDialog failureDialog = (AlertDialog) dialog;
failureDialog.setMessage(getString(resultMessage));
break;
}
}
protected void showImportedTrack() {
long lastTrackId = importedTrackIds[importedTrackIds.length - 1];
Uri trackUri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, lastTrackId);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(trackUri, TracksColumns.CONTENT_ITEMTYPE);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
private void startTrackImport(final String fileName) { private void startTrackImport(final String fileName) {
progressDialog = new ProgressDialog(this); showDialog(PROGRESS_DIALOG);
progressDialog.setOwnerActivity(this);
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
progressDialog.setTitle(R.string.progress_title);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(getString(R.string.import_progress_message));
progressDialog.show();
Thread t = new Thread() { Thread t = new Thread() {
@Override @Override
public void run() { public void run() {
int message = R.string.success; resultMessage = R.string.success;
long[] trackIdsImported = null; importedTrackIds = null;
try { try {
try { try {
InputStream is = new FileInputStream(fileName); InputStream is = new FileInputStream(fileName);
trackIdsImported = GpxImporter.importGPXFile(is, providerUtils); importedTrackIds = GpxImporter.importGPXFile(is, providerUtils);
} catch (SAXException e) { } catch (SAXException e) {
Log.e(TAG, "Caught an unexpected exception.", e); Log.e(TAG, "Caught an unexpected exception.", e);
message = R.string.error_generic; resultMessage = R.string.error_generic;
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
Log.e(TAG, "Caught an unexpected exception.", e); Log.e(TAG, "Caught an unexpected exception.", e);
message = R.string.error_generic; resultMessage = R.string.error_generic;
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Caught an unexpected exception.", e); Log.e(TAG, "Caught an unexpected exception.", e);
message = R.string.error_unable_to_read_file; resultMessage = R.string.error_unable_to_read_file;
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log.e(TAG, "Caught an unexpected exception.", e); Log.e(TAG, "Caught an unexpected exception.", e);
message = R.string.error_invalid_gpx_format; resultMessage = R.string.error_invalid_gpx_format;
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {
Log.e(TAG, "Caught an unexpected exception.", e); Log.e(TAG, "Caught an unexpected exception.", e);
message = R.string.error_out_of_memory; resultMessage = R.string.error_out_of_memory;
} }
boolean success = (trackIdsImported != null && trackIdsImported.length > 0); boolean success = (importedTrackIds != null && importedTrackIds.length > 0);
onImportDone(success, message, trackIdsImported); showImportResult(success);
} finally { } finally {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
progressDialog.dismiss(); dismissDialog(PROGRESS_DIALOG);
} }
}); });
} }
@@ -129,44 +201,15 @@ public class ImportActivity extends Activity {
t.start(); t.start();
} }
private void onImportDone(boolean success, int message, final long[] trackIds) { private void showImportResult(boolean success) {
OnClickListener finishOnClick = new OnClickListener() { final int dialogToShow = success ? SUCCESS_DIALOG : FAILURE_DIALOG;
@Override
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
};
if (!success) {
DialogManager.showMessageDialog(this, message, false /* success */,
finishOnClick);
return;
}
// Show a dialog telling the user about the import, and asking if he wishes // Show a dialog telling the user about the import, and asking if he wishes
// to open the track right away. // to open the track right away.
final Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setCancelable(true);
dialogBuilder.setMessage(getString(R.string.import_success, trackIds.length));
dialogBuilder.setPositiveButton(android.R.string.ok, finishOnClick);
dialogBuilder.setNeutralButton(R.string.import_show_track, new OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
long lastTrackId = trackIds[trackIds.length - 1];
Uri trackUri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, lastTrackId);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(trackUri, TracksColumns.CONTENT_ITEMTYPE);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
});
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
dialogBuilder.show(); showDialog(dialogToShow);
} }
}); });
} }
@@ -18,7 +18,6 @@ package com.google.android.apps.mytracks.io.file;
import static com.google.android.apps.mytracks.Constants.TAG; import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants; 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.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat; import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
@@ -27,9 +26,12 @@ import com.google.android.apps.mytracks.util.UriUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -46,12 +48,15 @@ import java.io.File;
public class SaveActivity extends Activity { public class SaveActivity extends Activity {
public static final String EXTRA_SHARE_FILE = "share_file"; public static final String EXTRA_SHARE_FILE = "share_file";
public static final String EXTRA_FILE_FORMAT = "file_format"; public static final String EXTRA_FILE_FORMAT = "file_format";
private static final int RESULT_DIALOG = 1;
/* VisibleForTesting */ static final int PROGRESS_DIALOG = 2;
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
private long trackId; private long trackId;
private TrackWriter writer; private TrackWriter writer;
private boolean shareFile; private boolean shareFile;
private TrackFileFormat format; private TrackFileFormat format;
private WriteProgressController controller;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -99,7 +104,7 @@ public class SaveActivity extends Activity {
writer.setDirectory(dir); writer.setDirectory(dir);
} }
WriteProgressController controller = new WriteProgressController(this, writer); controller = new WriteProgressController(this, writer, PROGRESS_DIALOG);
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() { controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
@Override @Override
public void onComplete() { public void onComplete() {
@@ -138,14 +143,47 @@ public class SaveActivity extends Activity {
} }
private void showResultDialog() { private void showResultDialog() {
DialogManager.showMessageDialog(this, writer.getErrorMessage(), writer.wasSuccess(), removeDialog(RESULT_DIALOG);
new OnClickListener() { showDialog(RESULT_DIALOG);
@Override }
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss(); @Override
finish(); protected Dialog onCreateDialog(int id) {
} switch (id) {
}); case RESULT_DIALOG:
return createResultDialog();
case PROGRESS_DIALOG:
if (controller != null) {
return controller.createProgressDialog();
}
default:
return super.onCreateDialog(id);
}
}
private Dialog createResultDialog() {
boolean success = writer.wasSuccess();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(writer.getErrorMessage());
builder.setNeutralButton(R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss();
finish();
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
finish();
}
});
builder.setIcon(success ? android.R.drawable.ic_dialog_info :
android.R.drawable.ic_dialog_alert);
builder.setTitle(success ? R.string.success : R.string.error);
return builder.create();
} }
public static void handleExportTrackAction(Context ctx, long trackId, int actionCode) { public static void handleExportTrackAction(Context ctx, long trackId, int actionCode) {
@@ -15,7 +15,6 @@
*/ */
package com.google.android.apps.mytracks.io.file; package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.DialogManager;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
@@ -46,9 +45,10 @@ class WriteProgressController {
private final Activity activity; private final Activity activity;
private final TrackWriter writer; private final TrackWriter writer;
private final ProgressDialog dialog; private ProgressDialog dialog;
private OnCompletionListener onCompletionListener; private OnCompletionListener onCompletionListener;
private final int progressDialogId;
/** /**
* @param activity the activity associated with this write * @param activity the activity associated with this write
@@ -57,17 +57,10 @@ class WriteProgressController {
* interested in notification upon completion of the write, they should * interested in notification upon completion of the write, they should
* use {@link #setOnCompletionListener}. * use {@link #setOnCompletionListener}.
*/ */
public WriteProgressController(Activity activity, TrackWriter writer) { public WriteProgressController(Activity activity, TrackWriter writer, int progressDialogId) {
this.activity = activity; this.activity = activity;
this.writer = writer; this.writer = writer;
this.progressDialogId = progressDialogId;
dialog = new ProgressDialog(activity);
dialog.setIcon(android.R.drawable.ic_dialog_info);
dialog.setTitle(activity.getString(R.string.progress_title));
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage(activity.getString(R.string.write_progress_message));
dialog.setIndeterminate(true);
dialog.setOnCancelListener(dialogCancelListener);
writer.setOnCompletionListener(writerCompleteListener); writer.setOnCompletionListener(writerCompleteListener);
writer.setOnWriteListener(writerWriteListener); writer.setOnWriteListener(writerWriteListener);
@@ -78,9 +71,20 @@ class WriteProgressController {
this.onCompletionListener = onCompletionListener; this.onCompletionListener = onCompletionListener;
} }
public ProgressDialog createProgressDialog() {
dialog = new ProgressDialog(activity);
dialog.setIcon(android.R.drawable.ic_dialog_info);
dialog.setTitle(activity.getString(R.string.progress_title));
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage(activity.getString(R.string.write_progress_message));
dialog.setIndeterminate(true);
dialog.setOnCancelListener(dialogCancelListener);
return dialog;
}
/** Initiate an asynchronous write. */ /** Initiate an asynchronous write. */
public void startWrite() { public void startWrite() {
DialogManager.showDialogSafely(activity, dialog); activity.showDialog(progressDialogId);
writer.writeTrackAsync(); writer.writeTrackAsync();
} }
@@ -101,7 +105,7 @@ class WriteProgressController {
new TrackWriter.OnCompletionListener() { new TrackWriter.OnCompletionListener() {
@Override @Override
public void onComplete() { public void onComplete() {
DialogManager.dismissDialogSafely(activity, dialog); activity.dismissDialog(progressDialogId);
if (onCompletionListener != null) { if (onCompletionListener != null) {
onCompletionListener.onComplete(); onCompletionListener.onComplete();
@@ -58,7 +58,8 @@ public class ResultDialogFactory {
*/ */
public static AlertDialog makeDialog(Activity activity, List<SendResult> results, public static AlertDialog makeDialog(Activity activity, List<SendResult> results,
DialogInterface.OnClickListener onOkClickListener, DialogInterface.OnClickListener onOkClickListener,
DialogInterface.OnClickListener onShareClickListener) { DialogInterface.OnClickListener onShareClickListener,
DialogInterface.OnCancelListener onCancelListener) {
boolean success = true; boolean success = true;
for (SendResult result : results) { for (SendResult result : results) {
if (!result.isSuccess()) { if (!result.isSuccess()) {
@@ -84,6 +85,8 @@ public class ResultDialogFactory {
onShareClickListener); onShareClickListener);
} }
builder.setOnCancelListener(onCancelListener);
return builder.create(); return builder.create();
} }
@@ -21,7 +21,6 @@ import com.google.android.accounts.Account;
import com.google.android.apps.analytics.GoogleAnalyticsTracker; import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import com.google.android.apps.mytracks.AccountChooser; import com.google.android.apps.mytracks.AccountChooser;
import com.google.android.apps.mytracks.Constants; 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.MyMapsList;
import com.google.android.apps.mytracks.ProgressIndicator; import com.google.android.apps.mytracks.ProgressIndicator;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
@@ -40,11 +39,12 @@ import com.google.android.apps.mytracks.util.UriUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnClickListener;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@@ -66,6 +66,10 @@ import java.util.List;
public class SendActivity extends Activity implements ProgressIndicator { public class SendActivity extends Activity implements ProgressIndicator {
public static final String EXTRA_SHARE_LINK = "share_link"; public static final String EXTRA_SHARE_LINK = "share_link";
private static final int SEND_DIALOG = 1;
private static final int PROGRESS_DIALOG = 2;
/* @VisibleForTesting */ static final int DONE_DIALOG = 3;
// Services // Services
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
private SharedPreferences sharedPreferences; private SharedPreferences sharedPreferences;
@@ -101,6 +105,13 @@ public class SendActivity extends Activity implements ProgressIndicator {
private SendDialog sendDialog; private SendDialog sendDialog;
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
private final OnCancelListener finishOnCancelListener = new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
onAllDone();
}
};
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -134,20 +145,39 @@ public class SendActivity extends Activity implements ProgressIndicator {
sendTrackId = ContentUris.parseId(data); sendTrackId = ContentUris.parseId(data);
showDialog(SEND_DIALOG);
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case SEND_DIALOG:
return createSendDialog();
case PROGRESS_DIALOG:
return createProgressDialog();
case DONE_DIALOG:
return createDoneDialog();
}
return null;
}
private Dialog createSendDialog() {
sendDialog = new SendDialog(this); sendDialog = new SendDialog(this);
sendDialog.setOwnerActivity(this);
sendDialog.setOnClickListener(new OnClickListener() { sendDialog.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(DialogInterface arg0, int which) { public void onClick(DialogInterface dialog, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) { if (which != DialogInterface.BUTTON_POSITIVE) {
finish(); finish();
return; return;
} }
dialog.dismiss();
doSend(); doSend();
} }
}); });
sendDialog.show(); sendDialog.setOnCancelListener(finishOnCancelListener);
return sendDialog;
} }
@Override @Override
@@ -163,18 +193,9 @@ public class SendActivity extends Activity implements ProgressIndicator {
* Initiates the process to send tracks to google. * Initiates the process to send tracks to google.
* This is called once the user has selected sending options via the * This is called once the user has selected sending options via the
* SendToGoogleDialog. * SendToGoogleDialog.
*
* TODO: Change this whole flow to an actual state machine.
*/ */
private void doSend() { private void doSend() {
progressDialog = new ProgressDialog(this); showDialog(PROGRESS_DIALOG);
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()) { if (sendDialog.getSendToMyMaps()) {
sendToGoogleMapsOrPickMap(); sendToGoogleMapsOrPickMap();
@@ -188,6 +209,18 @@ public class SendActivity extends Activity implements ProgressIndicator {
} }
} }
private Dialog createProgressDialog() {
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
progressDialog.setTitle(R.string.progress_title);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(100);
progressDialog.setProgress(0);
return progressDialog;
}
private void sendToGoogleMapsOrPickMap() { private void sendToGoogleMapsOrPickMap() {
if (!sendDialog.getCreateNewMap()) { if (!sendDialog.getCreateNewMap()) {
// Ask the user to choose a map to upload into // Ask the user to choose a map to upload into
@@ -370,19 +403,24 @@ public class SendActivity extends Activity implements ProgressIndicator {
private void onSendToGoogleDone() { private void onSendToGoogleDone() {
tracker.dispatch(); tracker.dispatch();
final boolean sentToMyMaps = sendDialog.getSendToMyMaps();
final boolean sentToFusionTables = sendDialog.getSendToFusionTables();
List<SendResult> results = makeSendToGoogleResults();
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
progressDialog.dismiss(); Log.d(TAG, "Sending to Google done.");
progressDialog = null; dismissDialog(PROGRESS_DIALOG);
sendDialog = null; dismissDialog(SEND_DIALOG);
// Ensure a new done dialog is created each time.
// This is required because the send results must be available at the
// time the dialog is created.
removeDialog(DONE_DIALOG);
showDialog(DONE_DIALOG);
} }
}); });
}
private Dialog createDoneDialog() {
Log.d(TAG, "Creating done dialog");
// We've finished sending the track to the user-selected services. Now // 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. // we tell them the results of the upload, and optionally share the track.
// There are a few different paths through this code: // There are a few different paths through this code:
@@ -401,14 +439,16 @@ public class SendActivity extends Activity implements ProgressIndicator {
// which we succeeded in uploading the track are incompatible with // which we succeeded in uploading the track are incompatible with
// sharing. We won't display a share button. // sharing. We won't display a share button.
final boolean canShare = sendToFusionTablesTableId != null final boolean sentToMyMaps = sendDialog.getSendToMyMaps();
|| sendToMyMapsMapId != null; final boolean sentToFusionTables = sendDialog.getSendToFusionTables();
List<SendResult> results = makeSendToGoogleResults();
final boolean canShare = sendToFusionTablesTableId != null || sendToMyMapsMapId != null;
final OnClickListener finishListener = new DialogInterface.OnClickListener() { final OnClickListener finishListener = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); dialog.dismiss();
finish(); onAllDone();
} }
}; };
@@ -417,11 +457,13 @@ public class SendActivity extends Activity implements ProgressIndicator {
doShareListener = new DialogInterface.OnClickListener() { doShareListener = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (!shareLinkToMap(sentToMyMaps, sentToFusionTables)) { if (!shareLinkToMap(sentToMyMaps, sentToFusionTables)) {
Log.w(TAG, "Failed to share link"); Log.w(TAG, "Failed to share link");
} }
finishListener.onClick(dialog, which); onAllDone();
} }
}; };
} }
@@ -431,9 +473,17 @@ public class SendActivity extends Activity implements ProgressIndicator {
DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested) DialogInterface.OnClickListener onShareListener = (canShare && !shareRequested)
? doShareListener : null; ? doShareListener : null;
AlertDialog sendToGoogleResultDialog = ResultDialogFactory.makeDialog(this, return ResultDialogFactory.makeDialog(this, results, onOkListener, onShareListener, finishOnCancelListener);
results, onOkListener, onShareListener); }
DialogManager.showDialogSafely(this, sendToGoogleResultDialog);
private void onAllDone() {
Log.d(TAG, "All sending done.");
removeDialog(PROGRESS_DIALOG);
removeDialog(SEND_DIALOG);
removeDialog(DONE_DIALOG);
progressDialog = null;
sendDialog = null;
finish();
} }
boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) { boolean shareLinkToMap(boolean sentToMyMaps, boolean sentToFusionTables) {
@@ -535,9 +585,9 @@ public class SendActivity extends Activity implements ProgressIndicator {
@Override @Override
public void onAccountSelected(Account account) { public void onAccountSelected(Account account) {
if (account == null) { if (account == null) {
progressDialog.dismiss(); dismissDialog(PROGRESS_DIALOG);
progressDialog = null;
finish(); finish();
return;
} }
doLogin(results, requestCode, service, account); doLogin(results, requestCode, service, account);
@@ -565,7 +615,8 @@ public class SendActivity extends Activity implements ProgressIndicator {
// make this return path explicit. // make this return path explicit.
if (resultCode != RESULT_OK || lastAuth == null || if (resultCode != RESULT_OK || lastAuth == null ||
!lastAuth.authResult(resultCode, results)) { !lastAuth.authResult(resultCode, results)) {
progressDialog.dismiss(); dismissDialog(PROGRESS_DIALOG);
finish();
} }
break; break;
} }
@@ -15,10 +15,6 @@
*/ */
package com.google.android.apps.mytracks.io.file; package com.google.android.apps.mytracks.io.file;
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.app.ProgressDialog;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
@@ -30,9 +26,9 @@ import java.util.concurrent.atomic.AtomicReference;
* *
* @author Matthew Simmons * @author Matthew Simmons
*/ */
public class WriteProgressControllerTest extends ActivityInstrumentationTestCase2<MyTracks> { public class WriteProgressControllerTest extends ActivityInstrumentationTestCase2<SaveActivity> {
public WriteProgressControllerTest() { public WriteProgressControllerTest() {
super(MyTracks.class); super(SaveActivity.class);
} }
private static void assertProgress(ProgressDialog dialog, int expectedProgress, private static void assertProgress(ProgressDialog dialog, int expectedProgress,
@@ -58,7 +54,7 @@ public class WriteProgressControllerTest extends ActivityInstrumentationTestCase
}; };
WriteProgressController controller = new WriteProgressController( WriteProgressController controller = new WriteProgressController(
getActivity(), mockWriter); getActivity(), mockWriter, SaveActivity.PROGRESS_DIALOG);
controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() { controller.setOnCompletionListener(new WriteProgressController.OnCompletionListener() {
@Override @Override
public void onComplete() { public void onComplete() {
@@ -66,7 +62,7 @@ public class WriteProgressControllerTest extends ActivityInstrumentationTestCase
} }
}); });
dialogRef.set(controller.getDialog()); dialogRef.set(controller.createProgressDialog());
controller.startWrite(); controller.startWrite();
@@ -15,7 +15,6 @@
*/ */
package com.google.android.apps.mytracks.io.sendtogoogle; package com.google.android.apps.mytracks.io.sendtogoogle;
import com.google.android.apps.mytracks.MyTracks;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.AlertDialog; import android.app.AlertDialog;
@@ -33,9 +32,9 @@ import java.util.List;
* *
* @author Matthew Simmons * @author Matthew Simmons
*/ */
public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<MyTracks> { public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<SendActivity> {
public ResultDialogFactoryTest() { public ResultDialogFactoryTest() {
super(MyTracks.class); super(SendActivity.class);
} }
private List<SendResult> makeResults(SendResult... results) { private List<SendResult> makeResults(SendResult... results) {
@@ -55,7 +54,7 @@ public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<My
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true), List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, true)); new SendResult(SendType.DOCS, true));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null); AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null, null);
dialog.show(); dialog.show();
ListView listView = (ListView) dialog.findViewById(R.id.send_to_google_result_list); ListView listView = (ListView) dialog.findViewById(R.id.send_to_google_result_list);
@@ -87,7 +86,7 @@ public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<My
new SendResult(SendType.DOCS, true)); new SendResult(SendType.DOCS, true));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results,
clickListener, clickListener); clickListener, clickListener, null);
dialog.show(); dialog.show();
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility()); assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility());
@@ -98,7 +97,7 @@ public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<My
List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true), List<SendResult> results = makeResults(new SendResult(SendType.MYMAPS, true),
new SendResult(SendType.DOCS, false)); new SendResult(SendType.DOCS, false));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null); AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, clickListener, null, null);
dialog.show(); dialog.show();
assertEquals(View.GONE, assertEquals(View.GONE,
@@ -112,7 +111,7 @@ public class ResultDialogFactoryTest extends ActivityInstrumentationTestCase2<My
new SendResult(SendType.DOCS, false)); new SendResult(SendType.DOCS, false));
AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results, AlertDialog dialog = ResultDialogFactory.makeDialog(getActivity(), results,
clickListener, clickListener); clickListener, clickListener, null);
dialog.show(); dialog.show();
assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility()); assertEquals(View.VISIBLE, dialog.getButton(AlertDialog.BUTTON_POSITIVE).getVisibility());