Merge SaveAllActivity to SaveActivity.

This commit is contained in:
Jimmy Shih
2012-05-15 17:25:04 -07:00
parent 3d3af298af
commit cabe966d27
11 changed files with 230 additions and 438 deletions
-1
View File
@@ -165,7 +165,6 @@ limitations under the License.
android:name="android.app.default_searchable"
android:value="com.google.android.apps.mytracks.SearchListActivity" />
</activity>
<activity android:name="com.google.android.apps.mytracks.SaveAllActivity" />
<activity
android:launchMode="singleTop"
android:name="com.google.android.apps.mytracks.SearchListActivity" >
+53 -75
View File
@@ -844,14 +844,7 @@ limitations under the License.
Track
</string>
<!-- Import -->
<string name="import_error"
translation_description="When importing all the tracks, a toast message indicating import error
for one of the tracks.
%1$s: the track's file path on the SD card. E.g., '/mnt/sdcard/MyTacks/gpx/1.gpx'.">
Import error for file %1$s.
</string>
<!-- Import GPX Files -->
<string name="import_gpx_files_few"
translation_description="When importing all the tracks, phrase for 'few' GPX files.
@@ -883,27 +876,6 @@ limitations under the License.
translation_description="When importing all the tracks, phrase for 0 GPX files.">
0 GPX files
</string>
<string name="import_no_file"
translation_description="After importing all the tracks from the SD card, the alert message
indicating that no track is imported.
%1$s: the SD card directory path. E.g., '/mnt/sdcard/MyTracks/gpx/'.">
No GPX file found in %1$s. The SD card may be unreadable or the directory may not contain any
GPX file.
</string>
<string name="import_progress_message"
translation_description="When importing all the tracks from the SD card, the progress message.">
Importing all tracks...
</string>
<string name="import_success"
translation_description="After importing all the tracks from the SD card, the alert message
indicating success.
%1$d the number of successfully imported tracks. E.g., '1'.
%2$s the number of GPX files in the SD card. E.g., '1 GPX file' or '2 GPX files'.
%3$s the SD card directory path. E.g., '/mnt/sdcard/MyTracks/gpx/'.">
My Tracks: Imported %1$d of %2$s from %3$s.
</string>
<!-- Maps List -->
<string name="maps_list_error"
@@ -1179,63 +1151,69 @@ limitations under the License.
write data to My Tracks and start/stop My Tracks recording
</string>
<!-- Save All -->
<string name="save_all_error"
translation_description="When saving all the tracks to the SD card, a toast message indicating
error.">
Unable to save.
</string>
<string name="save_all_progress_message"
translation_description="When saving all the tracks to the SD card, the progress message.">
Saving all tracks...
</string>
<string name="save_all_success"
translation_description="When saving all the tracks to the SD card, a toast message indicating
success.">
Save finished.
</string>
<!-- SD Card -->
<string name="sd_card_canceled"
translation_description="When exporting a track to the SD card, a message indicating that the
export operation was canceled.">
translation_description="When importing/saving to the SD card, the message indicating that the
operation was canceled.">
The operation was canceled.
</string>
<string name="sd_card_error_create_dir"
translation_description="When writing to the SD card, the error message when not able to create
a directory on the SD card.">
Unable to create a directory on the SD card.
</string>
<string name="sd_card_error_no_storage"
translation_description="When writing to the SD card, the error message when the SD card is not
found.">
No external storage was found. Make sure that a SD card is inserted and that your phone is not
mounted to a computer.
translation_description="When importing/saving to the SD card, the error message indicating that
no SD card is found.">
No SD card is found.
</string>
<string name="sd_card_error_read_file"
translation_description="When reading from the SD card, the error message when not able to read
a file.">
Unable to read from a file.
<string name="sd_card_import_error"
translation_description="When importing from the SD card, the error message indicating not able
to import.">
Unable to import from SD card.
</string>
<string name="sd_card_error_write_file"
translation_description="When writing to the SD card, the error message when not able to write a
file.">
Unable to write to a file.
<string name="sd_card_import_error_no_file"
translation_description="When importing from the SD card, the error message indicating that no
file is found on a SD card directory.
%1$s: the SD card directory. E.g., '/mnt/sdcard/MyTracks/gpx/'.">
No file found in %1$s.
</string>
<string name="sd_card_import_progress_message"
translation_description="When importing from the SD card, the progress message.">
Importing from SD card...
</string>
<string name="sd_card_progress_message"
translation_description="When saving a track to the SD card, the progress message.">
Saving to the SD card...
<string name="sd_card_import_success"
translation_description="When importing from the SD card, the success message.">
Finished importing from SD card.
</string>
<string name="sd_card_success_read_file"
translation_description="When reading from the SD card, the success message when finish reading
from the SD card.">
Finished reading from the SD card.
<string name="sd_card_import_success_count"
translation_description="When importing from the SD card, the success message with a count of
the imported files.
%1$d the number of successfully imported tracks. E.g., '1'.
%2$s the number of files in the SD card. E.g., '1 GPX file' or '2 GPX files'.
%3$s the SD card directory. E.g., '/mnt/sdcard/MyTracks/gpx/'.">
Imported %1$d of %2$s from %3$s.
</string>
<string name="sd_card_success_write_file"
translation_description="When writing to the SD card, the success message when finish writing to
the SD card.">
Finished writing to the SD card.
<string name="sd_card_save_error"
translation_description="When saving to the SD card, the error message indicating not able to
save.">
Unable to save to SD card.
</string>
<string name="sd_card_save_error_create_dir"
translation_description="When saving to the SD card, the error message indicating not able to
create a directory on the SD card.">
Unable to create a directory on SD card.
</string>
<string name="sd_card_save_error_no_track"
translation_description="When saving to the SD card, the error message indicating that no track
is available.">
You have no track to save to SD card.
</string>
<string name="sd_card_save_progress_message"
translation_description="When saving to the SD card, the progress message.">
Saving to SD card...
</string>
<string name="sd_card_save_success"
translation_description="When saving to the SD card, the success message">
Finished saving to SD card.
</string>
<!-- Search -->
<string name="search_global_description"
@@ -111,7 +111,7 @@ public class ImportActivity extends Activity {
switch (id) {
case DIALOG_PROGRESS_ID:
progressDialog = DialogUtils.createHorizontalProgressDialog(
this, R.string.import_progress_message, new DialogInterface.OnCancelListener() {
this, R.string.sd_card_import_progress_message, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
importAsyncTask.cancel(true);
@@ -122,11 +122,12 @@ public class ImportActivity extends Activity {
case DIALOG_RESULT_ID:
String message;
if (successCount == 0) {
message = getString(R.string.import_no_file, path);
message = getString(R.string.sd_card_import_error_no_file, path);
} else {
String totalFiles = getResources()
.getQuantityString(R.plurals.importGpxFiles, totalCount, totalCount);
message = getString(R.string.import_success, successCount, totalFiles, path);
message = getString(
R.string.sd_card_import_success_count, successCount, totalFiles, path);
}
return new AlertDialog.Builder(this)
.setCancelable(true)
@@ -171,7 +172,8 @@ public class ImportActivity extends Activity {
if (success) {
showDialog(DIALOG_RESULT_ID);
} else {
Toast.makeText(this, getString(R.string.import_error, path), Toast.LENGTH_LONG).show();
Toast.makeText(this, getString(R.string.sd_card_import_error), Toast.LENGTH_LONG)
.show();
finish();
}
}
@@ -1,115 +0,0 @@
/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
/**
* An activity to save all the tracks to the SD card.
*
* @author Sandor Dornbush
*/
public class SaveAllActivity extends Activity {
public static final String EXTRA_TRACK_FILE_FORMAT = "track_file_format";
private static final int DIALOG_PROGRESS_ID = 0;
private SaveAllAsyncTask saveAllAsyncTask;
private ProgressDialog progressDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Object retained = getLastNonConfigurationInstance();
if (retained instanceof SaveAllAsyncTask) {
saveAllAsyncTask = (SaveAllAsyncTask) retained;
saveAllAsyncTask.setActivity(this);
} else {
Intent intent = getIntent();
TrackFileFormat trackFileFormat = intent.getParcelableExtra(EXTRA_TRACK_FILE_FORMAT);
saveAllAsyncTask = new SaveAllAsyncTask(this, trackFileFormat);
saveAllAsyncTask.execute();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
saveAllAsyncTask.setActivity(null);
return saveAllAsyncTask;
}
@Override
protected Dialog onCreateDialog(int id) {
if (id != DIALOG_PROGRESS_ID) {
return null;
}
progressDialog = DialogUtils.createHorizontalProgressDialog(
this, R.string.save_all_progress_message, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
saveAllAsyncTask.cancel(true);
finish();
}
});
return progressDialog;
}
/**
* Invokes when the associated AsyncTask completes.
*
* @param success true if the AsyncTask is successful
* @param messageId message id to display to user
*/
public void onAsyncTaskCompleted(boolean success, int messageId) {
removeDialog(DIALOG_PROGRESS_ID);
Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
finish();
}
/**
* Shows the progress dialog.
*/
public void showProgressDialog() {
showDialog(DIALOG_PROGRESS_ID);
}
/**
* Sets the progress dialog value.
*
* @param number the number of tracks saved
* @param max the maximum number of tracks
*/
public void setProgressDialogValue(int number, int max) {
if (progressDialog != null) {
progressDialog.setIndeterminate(false);
progressDialog.setMax(max);
progressDialog.setProgress(Math.min(number, max));
}
}
}
@@ -1,162 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TracksColumns;
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.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.PowerManager.WakeLock;
/**
* AsyncTask to save all the tracks to the SD card.
*
* @author Jimmy Shih
*/
public class SaveAllAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private SaveAllActivity saveAllActivity;
private final TrackFileFormat trackFileFormat;
private final Context context;
private final MyTracksProviderUtils myTracksProviderUtils;
private WakeLock wakeLock;
private TrackWriter trackWriter;
// true if the AsyncTask result is success
private boolean success;
// true if the AsyncTask has completed
private boolean completed;
// message id to return to the activity
private int messageId;
/**
* Creates an AsyncTask.
*
* @param saveAllActivity the activity currently associated with this AsyncTask
* @param trackFileFormat the track file format
*/
public SaveAllAsyncTask(SaveAllActivity saveAllActivity, TrackFileFormat trackFileFormat) {
this.saveAllActivity = saveAllActivity;
this.trackFileFormat = trackFileFormat;
context = saveAllActivity.getApplicationContext();
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(saveAllActivity);
// Get the wake lock if not recording
if (PreferencesUtils.getLong(saveAllActivity, R.string.recording_track_id_key)
== PreferencesUtils.RECORDING_TRACK_ID_DEFAULT) {
wakeLock = SystemUtils.acquireWakeLock(saveAllActivity, wakeLock);
}
success = false;
completed = false;
messageId = R.string.save_all_error;
}
/**
* Sets the current {@link SaveAllActivity} associated with this AyncTask.
*
* @param saveAllActivity the current {@link SaveAllActivity}, can be null
*/
public void setActivity(SaveAllActivity saveAllActivity) {
this.saveAllActivity = saveAllActivity;
if (completed && saveAllActivity != null) {
saveAllActivity.onAsyncTaskCompleted(success, messageId);
}
}
@Override
protected void onPreExecute() {
if (saveAllActivity != null) {
saveAllActivity.showProgressDialog();
}
}
@Override
protected Boolean doInBackground(Void... params) {
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getTracksCursor(null, null, TracksColumns._ID);
if (cursor == null) {
messageId = R.string.save_all_success;
return true;
}
int count = cursor.getCount();
int idIndex = cursor.getColumnIndexOrThrow(TracksColumns._ID);
for (int i = 0; i < count; i++) {
if (isCancelled()) {
return false;
}
cursor.moveToPosition(i);
long id = cursor.getLong(idIndex);
trackWriter = TrackWriterFactory.newWriter(
context, myTracksProviderUtils, id, trackFileFormat);
if (trackWriter == null) {
return false;
}
trackWriter.writeTrack();
if (!trackWriter.wasSuccess()) {
messageId = trackWriter.getErrorMessage();
return false;
}
publishProgress(i + 1, count);
}
messageId = R.string.save_all_success;
return true;
} finally {
if (cursor != null) {
cursor.close();
}
// Release the wake lock if obtained
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
if (saveAllActivity != null) {
saveAllActivity.setProgressDialogValue(values[0], values[1]);
}
}
@Override
protected void onPostExecute(Boolean result) {
success = result;
completed = true;
if (saveAllActivity != null) {
saveAllActivity.onAsyncTaskCompleted(success, messageId);
}
}
@Override
protected void onCancelled() {
if (trackWriter != null) {
trackWriter.stopWriteTrack();
}
}
}
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment.DeleteOneTrackCaller;
import com.google.android.apps.mytracks.fragments.EulaDialogFragment;
import com.google.android.apps.mytracks.fragments.WelcomeDialogFragment;
import com.google.android.apps.mytracks.io.file.SaveActivity;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.services.ITrackRecordingService;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
@@ -399,24 +400,16 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
startActivity(intent);
return true;
case R.id.track_list_save_all_gpx:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.GPX);
startActivity(intent);
startSaveActivity(TrackFileFormat.GPX);
return true;
case R.id.track_list_save_all_kml:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML);
startActivity(intent);
startSaveActivity(TrackFileFormat.KML);
return true;
case R.id.track_list_save_all_csv:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.CSV);
startActivity(intent);
startSaveActivity(TrackFileFormat.CSV);
return true;
case R.id.track_list_save_all_tcx:
intent = IntentUtils.newIntent(this, SaveAllActivity.class)
.putExtra(SaveAllActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.TCX);
startActivity(intent);
startSaveActivity(TrackFileFormat.TCX);
return true;
case R.id.track_list_delete_all:
new DeleteAllTrackDialogFragment().show(
@@ -439,6 +432,17 @@ public class TrackListActivity extends FragmentActivity implements DeleteOneTrac
}
}
/**
* Starts the {@link SaveActivity} to save all tracks.
*
* @param trackFileFormat the track file format
*/
private void startSaveActivity(TrackFileFormat trackFileFormat) {
Intent intent = IntentUtils.newIntent(this, SaveActivity.class)
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat);
startActivity(intent);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
@@ -56,7 +56,7 @@ public class BackupAsyncTask extends AsyncTask<Void, Integer, Boolean> {
this.externalFileBackup = new ExternalFileBackup(backupActivity);
success = false;
completed = false;
messageId = R.string.sd_card_error_write_file;
messageId = R.string.sd_card_save_error;
}
/**
@@ -86,13 +86,13 @@ public class BackupAsyncTask extends AsyncTask<Void, Integer, Boolean> {
}
if (!externalFileBackup.isBackupsDirectoryAvailable(true)) {
messageId = R.string.sd_card_error_create_dir;
messageId = R.string.sd_card_save_error_create_dir;
return false;
}
try {
externalFileBackup.writeToDefaultFile();
messageId = R.string.sd_card_success_write_file;
messageId = R.string.sd_card_save_success;
return true;
} catch (IOException e) {
Log.d(TAG, "IO exception", e);
@@ -59,7 +59,7 @@ public class RestoreAsyncTask extends AsyncTask<Void, Integer, Boolean> {
this.externalFileBackup = new ExternalFileBackup(restoreActivity);
success = false;
completed = false;
messageId = R.string.sd_card_error_read_file;
messageId = R.string.sd_card_import_error;
}
/**
@@ -85,7 +85,7 @@ public class RestoreAsyncTask extends AsyncTask<Void, Integer, Boolean> {
protected Boolean doInBackground(Void... params) {
try {
externalFileBackup.restoreFromDate(date);
messageId = R.string.sd_card_success_read_file;
messageId = R.string.sd_card_import_success;
return true;
} catch (IOException e) {
Log.d(TAG, "IO exception", e);
@@ -16,10 +16,8 @@
package com.google.android.apps.mytracks.io.file;
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.DialogUtils;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
@@ -30,20 +28,18 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import java.io.File;
/**
* Activity for saving a track to the SD card, and optionally share or play the
* track.
* An activity for saving tracks to the SD card, and optionally play the track.
*
* @author Rodrigo Damazio
*/
public class SaveActivity extends Activity {
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_TRACK_FILE_FORMAT = "track_file_format";
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_SHARE_TRACK = "share_track";
public static final String EXTRA_PLAY_TRACK = "play_track";
@@ -55,13 +51,11 @@ public class SaveActivity extends Activity {
GOOGLE_EARTH_TOUR_FEATURE_ID = "com.google.earth.EXTRA.tour_feature_id";
private static final String GOOGLE_EARTH_CLASS = "com.google.earth.EarthActivity";
private static final String TAG = SaveActivity.class.getSimpleName();
private static final int DIALOG_PROGRESS_ID = 0;
private static final int DIALOG_RESULT_ID = 1;
private long trackId;
private TrackFileFormat trackFileFormat;
private long trackId;
private boolean shareTrack;
private boolean playTrack;
@@ -74,22 +68,16 @@ public class SaveActivity extends Activity {
// message id from the AsyncTask
private int messageId;
// path of the saved file
private String filePath;
// saved file path from the AsyncTask
private String savedPath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
if (trackId < 0) {
Log.d(TAG, "Invalid track id");
finish();
return;
}
trackFileFormat = intent.getParcelableExtra(EXTRA_TRACK_FILE_FORMAT);
trackId = intent.getLongExtra(EXTRA_TRACK_ID, -1L);
shareTrack = intent.getBooleanExtra(EXTRA_SHARE_TRACK, false);
playTrack = intent.getBooleanExtra(EXTRA_PLAY_TRACK, false);
@@ -98,20 +86,7 @@ public class SaveActivity extends Activity {
saveAsyncTask = (SaveAsyncTask) retained;
saveAsyncTask.setActivity(this);
} else {
TrackWriter trackWriter = TrackWriterFactory.newWriter(
this, MyTracksProviderUtils.Factory.get(this), trackId, trackFileFormat);
if (trackWriter == null) {
Log.e(TAG, "Track writer is null");
finish();
return;
}
if (shareTrack || playTrack) {
// Save to the temp directory
String dirName = FileUtils.buildExternalDirectoryPath(
trackFileFormat.getExtension(), "tmp");
trackWriter.setDirectory(new File(dirName));
}
saveAsyncTask = new SaveAsyncTask(this, trackWriter);
saveAsyncTask = new SaveAsyncTask(this, trackFileFormat, trackId, shareTrack || playTrack);
saveAsyncTask.execute();
}
}
@@ -127,7 +102,7 @@ public class SaveActivity extends Activity {
switch (id) {
case DIALOG_PROGRESS_ID:
progressDialog = DialogUtils.createHorizontalProgressDialog(
this, R.string.sd_card_progress_message, new DialogInterface.OnCancelListener() {
this, R.string.sd_card_save_progress_message, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
saveAsyncTask.cancel(true);
@@ -167,12 +142,12 @@ public class SaveActivity extends Activity {
*
* @param isSuccess true if the AsyncTask is successful
* @param aMessageId the id of the AsyncTask message
* @param aPath the path of the saved file
* @param aSavedPath the path of the saved file
*/
public void onAsyncTaskCompleted(boolean isSuccess, int aMessageId, String aPath) {
public void onAsyncTaskCompleted(boolean isSuccess, int aMessageId, String aSavedPath) {
this.success = isSuccess;
this.messageId = aMessageId;
this.filePath = aPath;
this.savedPath = aSavedPath;
removeDialog(DIALOG_PROGRESS_ID);
showDialog(DIALOG_RESULT_ID);
}
@@ -205,7 +180,7 @@ public class SaveActivity extends Activity {
if (success) {
if (shareTrack) {
Intent intent = new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filePath)))
.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(savedPath)))
.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_track_subject))
.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_track_file_body_format))
.putExtra(getString(R.string.track_id_broadcast_extra), trackId)
@@ -216,7 +191,7 @@ public class SaveActivity extends Activity {
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(GOOGLE_EARTH_TOUR_FEATURE_ID, KmlTrackWriter.TOUR_FEATURE_ID)
.setClassName(GOOGLE_EARTH_PACKAGE, GOOGLE_EARTH_CLASS)
.setDataAndType(Uri.fromFile(new File(filePath)), GOOGLE_EARTH_KML_MIME_TYPE);
.setDataAndType(Uri.fromFile(new File(savedPath)), GOOGLE_EARTH_KML_MIME_TYPE);
startActivity(intent);
}
}
@@ -16,48 +16,93 @@
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.SystemUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import java.io.File;
/**
* Async Task to save a track to the SD card.
*
* Async Task to save tracks to the SD card.
*
* @author Jimmy Shih
*/
public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private static final String TAG = SaveAsyncTask.class.getSimpleName();
private SaveActivity saveActivity;
private final TrackWriter trackWriter;
private final TrackFileFormat trackFileFormat;
private final long trackId;
private final boolean useTempDir;
private final Context context;
private final MyTracksProviderUtils myTracksProviderUtils;
private WakeLock wakeLock;
private TrackWriter trackWriter;
// true if the AsyncTask result is success
private boolean success;
// true if the AsyncTask has completed
private boolean completed;
// message id to return to the activity
private int messageId;
// saved file path to return to the activity
private String savedPath;
/**
* Creates an AsyncTask.
*
* @param saveActivity the {@link SaveActivity} currently associated with this
* AsyncTask
* @param trackWriter the track writer
*
* @param saveActivity the activity currently associated with this task.
* @param trackFileFormat the track format
* @param trackId the track id
* @param useTempDir true to use the temp directory
*/
public SaveAsyncTask(SaveActivity saveActivity, TrackWriter trackWriter) {
public SaveAsyncTask(SaveActivity saveActivity, TrackFileFormat trackFileFormat, long trackId,
boolean useTempDir) {
this.saveActivity = saveActivity;
this.trackWriter = trackWriter;
this.trackFileFormat = trackFileFormat;
this.trackId = trackId;
this.useTempDir = useTempDir;
context = saveActivity.getApplicationContext();
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(saveActivity);
// Get the wake lock if not recording
if (PreferencesUtils.getLong(saveActivity, R.string.recording_track_id_key)
== PreferencesUtils.RECORDING_TRACK_ID_DEFAULT) {
wakeLock = SystemUtils.acquireWakeLock(saveActivity, wakeLock);
}
trackWriter = null;
success = false;
completed = false;
messageId = R.string.sd_card_save_error;
savedPath = null;
}
/**
* Sets the current {@link SaveActivity} associated with this AyncTask.
*
* @param saveActivity the current {@link SaveActivity}, can be null
* Sets the current activity associated with this AyncTask.
*
* @param saveActivity the current activity, can be null
*/
public void setActivity(SaveActivity saveActivity) {
this.saveActivity = saveActivity;
if (completed && saveActivity != null) {
saveActivity.onAsyncTaskCompleted(
success, trackWriter.getErrorMessage(), trackWriter.getAbsolutePath());
saveActivity.onAsyncTaskCompleted(success, messageId, savedPath);
}
}
@@ -69,20 +114,85 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
}
@Override
protected Boolean doInBackground(Void... params) {
protected Boolean doInBackground(Void... params) {
try {
if (trackId != -1L) {
return saveOneTrack(trackId, true);
} else {
return saveAllTracks();
}
} finally {
// Release the wake lock if obtained
if (wakeLock != null && wakeLock.isHeld()) {
wakeLock.release();
}
}
}
/**
* Saves one track.
*
* @param id the track id
* @param updateSavingProgress true to update the saving progress
*/
private Boolean saveOneTrack(long id, final boolean updateSavingProgress) {
trackWriter = TrackWriterFactory.newWriter(
context, myTracksProviderUtils, id, trackFileFormat);
if (trackWriter == null) {
Log.e(TAG, "Track writer is null");
return false;
}
if (useTempDir) {
String dirName = FileUtils.buildExternalDirectoryPath(trackFileFormat.getExtension(), "tmp");
trackWriter.setDirectory(new File(dirName));
}
trackWriter.setOnWriteListener(new TrackWriter.OnWriteListener() {
@Override
@Override
public void onWrite(int number, int max) {
// Update the progress dialog once every 500 points
if (number % 500 == 0) {
if (updateSavingProgress && number % 500 == 0) {
publishProgress(number, max);
}
}
});
trackWriter.writeTrack();
messageId = trackWriter.getErrorMessage();
savedPath = trackWriter.getAbsolutePath();
return trackWriter.wasSuccess();
}
/**
* Saves all the tracks.
*/
private Boolean saveAllTracks() {
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getTracksCursor(null, null, TracksColumns._ID);
if (cursor == null) {
messageId = R.string.sd_card_save_error_no_track;
return false;
}
int count = cursor.getCount();
int idIndex = cursor.getColumnIndexOrThrow(TracksColumns._ID);
for (int i = 0; i < count; i++) {
if (isCancelled()) {
return false;
}
cursor.moveToPosition(i);
long id = cursor.getLong(idIndex);
if (!saveOneTrack(id, false)) {
return false;
}
publishProgress(i + 1, count);
}
messageId = R.string.sd_card_save_success;
return true;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
if (saveActivity != null) {
@@ -95,13 +205,14 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
success = result;
completed = true;
if (saveActivity != null) {
saveActivity.onAsyncTaskCompleted(
success, trackWriter.getErrorMessage(), trackWriter.getAbsolutePath());
saveActivity.onAsyncTaskCompleted(success, messageId, savedPath);
}
}
@Override
protected void onCancelled() {
trackWriter.stopWriteTrack();
if (trackWriter != null) {
trackWriter.stopWriteTrack();
}
}
}
@@ -53,7 +53,7 @@ class TrackWriterImpl implements TrackWriter {
private final Track track;
private final TrackFormatWriter writer;
private boolean success = false;
private int errorMessage = -1;
private int errorMessage = R.string.sd_card_save_error;
private File directory = null;
private File file = null;
private OnWriteListener onWriteListener;
@@ -105,7 +105,7 @@ class TrackWriterImpl implements TrackWriter {
private void doWriteTrack() {
// Open the input and output
success = false;
errorMessage = R.string.sd_card_error_write_file;
errorMessage = R.string.sd_card_save_error;
if (track != null) {
if (openFile()) {
try {
@@ -186,7 +186,7 @@ class TrackWriterImpl implements TrackWriter {
writer.prepare(track, newOutputStream(fileName));
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "Failed to open output file.", e);
errorMessage = R.string.sd_card_error_write_file;
errorMessage = R.string.sd_card_save_error;
return false;
}
return true;
@@ -209,7 +209,7 @@ class TrackWriterImpl implements TrackWriter {
}
if (!FileUtils.ensureDirectoryExists(directory)) {
Log.i(Constants.TAG, "Could not create export directory.");
errorMessage = R.string.sd_card_error_create_dir;
errorMessage = R.string.sd_card_save_error_create_dir;
return false;
}
@@ -283,7 +283,7 @@ class TrackWriterImpl implements TrackWriter {
writer.close();
success = true;
Log.d(Constants.TAG, "Done writing track.");
errorMessage = R.string.sd_card_success_write_file;
errorMessage = R.string.sd_card_save_success;
}
private void writeLocations() throws InterruptedException {