forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -160,6 +160,26 @@ limitations under the License.
|
|||||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.google.android.apps.mytracks.ExportAllActivity"/>
|
<activity android:name="com.google.android.apps.mytracks.ExportAllActivity"/>
|
||||||
|
<activity
|
||||||
|
android:label="@string/my_tracks_importer"
|
||||||
|
android:name="com.google.android.apps.mytracks.ImportActivity"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="android.intent.action.ATTACH_DATA" />
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
|
<data android:mimeType="application/gpx" />
|
||||||
|
<data android:mimeType="application/gpx+xml" />
|
||||||
|
<data android:mimeType="application/vnd.google-earth.gpx" />
|
||||||
|
<data android:mimeType="application/vnd.google-earth.gpx+xml" />
|
||||||
|
<data android:scheme="file" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:name="com.google.android.apps.mytracks.MapActivity" >
|
android:name="com.google.android.apps.mytracks.MapActivity" >
|
||||||
@@ -264,25 +284,6 @@ limitations under the License.
|
|||||||
android:label="@string/welcome_title"
|
android:label="@string/welcome_title"
|
||||||
android:name="com.google.android.apps.mytracks.WelcomeActivity" />
|
android:name="com.google.android.apps.mytracks.WelcomeActivity" />
|
||||||
<activity android:name="com.google.android.apps.mytracks.io.docs.SendDocsActivity" />
|
<activity android:name="com.google.android.apps.mytracks.io.docs.SendDocsActivity" />
|
||||||
<activity
|
|
||||||
android:label="@string/my_tracks_importer"
|
|
||||||
android:name="com.google.android.apps.mytracks.io.file.ImportActivity"
|
|
||||||
android:noHistory="true"
|
|
||||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.ATTACH_DATA" />
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
|
|
||||||
<data android:mimeType="application/gpx" />
|
|
||||||
<data android:mimeType="application/gpx+xml" />
|
|
||||||
<data android:mimeType="application/vnd.google-earth.gpx" />
|
|
||||||
<data android:mimeType="application/vnd.google-earth.gpx+xml" />
|
|
||||||
<data android:scheme="file" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.google.android.apps.mytracks.io.file.SaveActivity"
|
android:name="com.google.android.apps.mytracks.io.file.SaveActivity"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 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.TracksColumns;
|
||||||
|
import com.google.android.apps.mytracks.util.FileUtils;
|
||||||
|
import com.google.android.apps.mytracks.util.UriUtils;
|
||||||
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.ContentUris;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An activity to import GPX files from the SD card. Optionally to import one
|
||||||
|
* GPX file and display it in My Tracks.
|
||||||
|
*
|
||||||
|
* @author Rodrigo Damazio
|
||||||
|
*/
|
||||||
|
public class ImportActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String EXTRA_IMPORT_ALL = "import_all";
|
||||||
|
|
||||||
|
private static final String TAG = ImportActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final int DIALOG_PROGRESS_ID = 0;
|
||||||
|
private static final int DIALOG_RESULT_ID = 1;
|
||||||
|
|
||||||
|
private ImportAsyncTask importAsyncTask;
|
||||||
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
|
private boolean importAll;
|
||||||
|
|
||||||
|
// path on the SD card to import
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
// number of succesfully imported files
|
||||||
|
private int successCount;
|
||||||
|
|
||||||
|
// number of files to import
|
||||||
|
private int totalCount;
|
||||||
|
|
||||||
|
// last successfully imported track id
|
||||||
|
private long trackId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Intent intent = getIntent();
|
||||||
|
importAll = intent.getBooleanExtra(EXTRA_IMPORT_ALL, false);
|
||||||
|
if (importAll) {
|
||||||
|
path = new FileUtils().buildExternalDirectoryPath("gpx");
|
||||||
|
} else {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (!(Intent.ACTION_ATTACH_DATA.equals(action) || Intent.ACTION_VIEW.equals(action))) {
|
||||||
|
Log.d(TAG, "Invalid action: " + intent);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri data = intent.getData();
|
||||||
|
if (!UriUtils.isFileUri(data)) {
|
||||||
|
Log.d(TAG, "Invalid data: " + intent);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
path = data.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object retained = getLastNonConfigurationInstance();
|
||||||
|
if (retained instanceof ImportAsyncTask) {
|
||||||
|
importAsyncTask = (ImportAsyncTask) retained;
|
||||||
|
importAsyncTask.setActivity(this);
|
||||||
|
} else {
|
||||||
|
importAsyncTask = new ImportAsyncTask(this, importAll, path);
|
||||||
|
importAsyncTask.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object onRetainNonConfigurationInstance() {
|
||||||
|
importAsyncTask.setActivity(null);
|
||||||
|
return importAsyncTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Dialog onCreateDialog(int id) {
|
||||||
|
switch (id) {
|
||||||
|
case DIALOG_PROGRESS_ID:
|
||||||
|
progressDialog = new ProgressDialog(this);
|
||||||
|
progressDialog.setCancelable(true);
|
||||||
|
progressDialog.setIcon(android.R.drawable.ic_dialog_info);
|
||||||
|
progressDialog.setIndeterminate(true);
|
||||||
|
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
importAsyncTask.cancel(true);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
progressDialog.setTitle(R.string.track_list_import_all);
|
||||||
|
return progressDialog;
|
||||||
|
case DIALOG_RESULT_ID:
|
||||||
|
String message;
|
||||||
|
if (successCount == 0) {
|
||||||
|
message = getString(R.string.import_no_file, path);
|
||||||
|
} else {
|
||||||
|
String totalFiles = getResources()
|
||||||
|
.getQuantityString(R.plurals.importGpxFiles, totalCount, totalCount);
|
||||||
|
message = getString(R.string.import_success, successCount, totalFiles, path);
|
||||||
|
}
|
||||||
|
return new AlertDialog.Builder(this).setCancelable(true)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setMessage(message)
|
||||||
|
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
if (!importAll && trackId != -1L) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.setDataAndType(
|
||||||
|
ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId),
|
||||||
|
TracksColumns.CONTENT_ITEMTYPE);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes when the associated AsyncTask completes.
|
||||||
|
*
|
||||||
|
* @param success true if the AsyncTask is successful
|
||||||
|
* @param imported the number of files successfully imported
|
||||||
|
* @param total the total number of files to import
|
||||||
|
* @param id the last successfully imported track id
|
||||||
|
*/
|
||||||
|
public void onAsyncTaskCompleted(boolean success, int imported, int total, long id) {
|
||||||
|
successCount = imported;
|
||||||
|
totalCount = total;
|
||||||
|
trackId = id;
|
||||||
|
removeDialog(DIALOG_PROGRESS_ID);
|
||||||
|
if (success) {
|
||||||
|
showDialog(DIALOG_RESULT_ID);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getString(R.string.import_error, path), 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 files imported
|
||||||
|
* @param max the maximum number of files
|
||||||
|
*/
|
||||||
|
public void setProgressDialogValue(int number, int max) {
|
||||||
|
if (progressDialog != null) {
|
||||||
|
progressDialog.setIndeterminate(false);
|
||||||
|
progressDialog.setMax(max);
|
||||||
|
progressDialog.setProgress(Math.min(number, max));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 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.GpxImporter;
|
|
||||||
import com.google.android.apps.mytracks.util.FileUtils;
|
|
||||||
import com.google.android.apps.mytracks.util.SystemUtils;
|
|
||||||
import com.google.android.maps.mytracks.R;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.ProgressDialog;
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.PowerManager.WakeLock;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class that will import all GPX tracks in /sdcard/MyTracks/gpx/
|
|
||||||
*
|
|
||||||
* @author David Piggott
|
|
||||||
*/
|
|
||||||
public class ImportAllTracks {
|
|
||||||
|
|
||||||
private final Activity activity;
|
|
||||||
private FileUtils fileUtils;
|
|
||||||
private boolean singleTrackSelected;
|
|
||||||
private String gpxPath;
|
|
||||||
private WakeLock wakeLock;
|
|
||||||
private ProgressDialog progress;
|
|
||||||
private int gpxFileCount;
|
|
||||||
private int importSuccessCount;
|
|
||||||
private long importedTrackIds[];
|
|
||||||
|
|
||||||
public ImportAllTracks(Activity activity) {
|
|
||||||
this(activity, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor to import tracks.
|
|
||||||
*
|
|
||||||
* @param activity the activity
|
|
||||||
* @param path path of the gpx file to import and display. If null, then just
|
|
||||||
* import all the gpx files under MyTracks/gpx and do not display any
|
|
||||||
* track.
|
|
||||||
*/
|
|
||||||
public ImportAllTracks(Activity activity, String path) {
|
|
||||||
Log.i(Constants.TAG, "ImportAllTracks: Starting");
|
|
||||||
this.activity = activity;
|
|
||||||
fileUtils = new FileUtils();
|
|
||||||
singleTrackSelected = path != null;
|
|
||||||
gpxPath = path == null ? fileUtils.buildExternalDirectoryPath("gpx") : path;
|
|
||||||
new Thread(runner).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Runnable runner = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
aquireLocksAndImport();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes sure that we keep the phone from sleeping. See if there is a current
|
|
||||||
* track. Acquire a wake lock if there is no current track.
|
|
||||||
*/
|
|
||||||
private void aquireLocksAndImport() {
|
|
||||||
SharedPreferences prefs = activity.getSharedPreferences(
|
|
||||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
||||||
long recordingTrackId = -1;
|
|
||||||
if (prefs != null) {
|
|
||||||
recordingTrackId = prefs.getLong(activity.getString(R.string.recording_track_key), -1);
|
|
||||||
}
|
|
||||||
if (recordingTrackId == -1) {
|
|
||||||
wakeLock = SystemUtils.acquireWakeLock(activity, wakeLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can safely import everything.
|
|
||||||
importAll();
|
|
||||||
|
|
||||||
// Release the wake lock if we acquired one.
|
|
||||||
// TODO check what happens if we started recording after getting this lock.
|
|
||||||
if (wakeLock != null && wakeLock.isHeld()) {
|
|
||||||
wakeLock.release();
|
|
||||||
Log.i(Constants.TAG, "ImportAllTracks: Releasing wake lock.");
|
|
||||||
}
|
|
||||||
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
showDoneDialog();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showDoneDialog() {
|
|
||||||
Log.i(Constants.TAG, "ImportAllTracks: Done");
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
|
||||||
if (gpxFileCount == 0) {
|
|
||||||
builder.setMessage(activity.getString(R.string.import_no_file, gpxPath));
|
|
||||||
} else {
|
|
||||||
String totalFiles = activity.getResources().getQuantityString(
|
|
||||||
R.plurals.importGpxFiles, gpxFileCount, gpxFileCount);
|
|
||||||
builder.setMessage(
|
|
||||||
activity.getString(R.string.import_success, importSuccessCount, totalFiles, gpxPath));
|
|
||||||
}
|
|
||||||
builder.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (singleTrackSelected) {
|
|
||||||
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);
|
|
||||||
activity.startActivity(intent);
|
|
||||||
activity.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeProgressDialog(final int trackCount) {
|
|
||||||
String importMsg = activity.getString(R.string.track_list_import_all);
|
|
||||||
progress = new ProgressDialog(activity);
|
|
||||||
progress.setIcon(android.R.drawable.ic_dialog_info);
|
|
||||||
progress.setTitle(importMsg);
|
|
||||||
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
|
||||||
progress.setMax(trackCount);
|
|
||||||
progress.setProgress(0);
|
|
||||||
progress.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actually import the tracks. This should be called after the wake locks have
|
|
||||||
* been acquired.
|
|
||||||
*/
|
|
||||||
private void importAll() {
|
|
||||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(activity);
|
|
||||||
|
|
||||||
if (!fileUtils.isSdCardAvailable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<File> gpxFiles = getGpxFiles();
|
|
||||||
gpxFileCount = gpxFiles.size();
|
|
||||||
if (gpxFileCount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(Constants.TAG, "ImportAllTracks: Importing: " + gpxFileCount + " tracks.");
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
makeProgressDialog(gpxFileCount);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Iterator<File> gpxFilesIterator = gpxFiles.iterator();
|
|
||||||
for (int currentFileNumber = 0; gpxFilesIterator.hasNext(); currentFileNumber++) {
|
|
||||||
File currentFile = gpxFilesIterator.next();
|
|
||||||
final int status = currentFileNumber;
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
synchronized (this) {
|
|
||||||
if (progress == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
progress.setProgress(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (importFile(currentFile, providerUtils)) {
|
|
||||||
importSuccessCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress != null) {
|
|
||||||
synchronized (this) {
|
|
||||||
progress.dismiss();
|
|
||||||
progress = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to import a GPX file. Returns true on success, issues error
|
|
||||||
* notifications and returns false on failure.
|
|
||||||
*/
|
|
||||||
private boolean importFile(final File gpxFile, MyTracksProviderUtils providerUtils) {
|
|
||||||
Log.i(Constants.TAG, "ImportAllTracks: importing: " + gpxFile.getName());
|
|
||||||
try {
|
|
||||||
importedTrackIds = GpxImporter.importGPXFile(new FileInputStream(gpxFile), providerUtils);
|
|
||||||
return true;
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.w(Constants.TAG, "GPX file wasn't found/went missing: "
|
|
||||||
+ gpxFile.getAbsolutePath(), e);
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
Log.w(Constants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
|
||||||
} catch (SAXException e) {
|
|
||||||
Log.w(Constants.TAG, "Error parsing file: " + gpxFile.getAbsolutePath(), e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(Constants.TAG, "Error reading file: " + gpxFile.getAbsolutePath(), e);
|
|
||||||
}
|
|
||||||
activity.runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Toast.makeText(activity, activity.getString(R.string.import_error, gpxFile.getName()),
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of the GPX files. If singleTrackSelected is true, returns a
|
|
||||||
* list containing just the gpxPath file. If singleTrackSelected is false,
|
|
||||||
* returns a list of GPX files under the gpxPath directory.
|
|
||||||
*/
|
|
||||||
private List<File> getGpxFiles() {
|
|
||||||
List<File> gpxFiles = new LinkedList<File>();
|
|
||||||
File file = new File(gpxPath);
|
|
||||||
if (singleTrackSelected) {
|
|
||||||
gpxFiles.add(file);
|
|
||||||
} else {
|
|
||||||
File[] gpxFileCandidates = file.listFiles();
|
|
||||||
if (gpxFileCandidates != null) {
|
|
||||||
for (File candidate : gpxFileCandidates) {
|
|
||||||
if (!candidate.isDirectory() && candidate.getName().endsWith(".gpx")) {
|
|
||||||
gpxFiles.add(candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return gpxFiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
/*
|
||||||
|
* 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.io.file.GpxImporter;
|
||||||
|
import com.google.android.apps.mytracks.util.FileUtils;
|
||||||
|
import com.google.android.apps.mytracks.util.SystemUtils;
|
||||||
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.PowerManager.WakeLock;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AsyncTask to import GPX files from the SD card.
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
|
|
||||||
|
private static final String TAG = ImportAsyncTask.class.getSimpleName();
|
||||||
|
|
||||||
|
private ImportActivity importActivity;
|
||||||
|
private final boolean importAll;
|
||||||
|
private final String path;
|
||||||
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
private WakeLock wakeLock;
|
||||||
|
|
||||||
|
// true if the AsyncTask result is success
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
// true if the AsyncTask has completed
|
||||||
|
private boolean completed;
|
||||||
|
|
||||||
|
// number of files successfully imported
|
||||||
|
private int successCount;
|
||||||
|
|
||||||
|
// number of files to import
|
||||||
|
private int totalCount;
|
||||||
|
|
||||||
|
// the last successfully imported track id
|
||||||
|
private long trackId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AsyncTask.
|
||||||
|
*
|
||||||
|
* @param importActivity the activity currently associated with this AsyncTask
|
||||||
|
* @param importAll true to import all GPX files
|
||||||
|
* @param path path to import GPX files
|
||||||
|
*/
|
||||||
|
public ImportAsyncTask(ImportActivity importActivity, boolean importAll, String path) {
|
||||||
|
this.importActivity = importActivity;
|
||||||
|
this.importAll = importAll;
|
||||||
|
this.path = path;
|
||||||
|
|
||||||
|
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(importActivity);
|
||||||
|
SharedPreferences sharedPreferences = importActivity.getSharedPreferences(
|
||||||
|
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
|
long recordingTrackId = sharedPreferences.getLong(
|
||||||
|
importActivity.getString(R.string.recording_track_key), -1L);
|
||||||
|
|
||||||
|
// Get the wake lock if not recording
|
||||||
|
if (recordingTrackId == -1L) {
|
||||||
|
wakeLock = SystemUtils.acquireWakeLock(importActivity, wakeLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
success = false;
|
||||||
|
completed = false;
|
||||||
|
successCount = 0;
|
||||||
|
totalCount = 0;
|
||||||
|
trackId = -1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current {@link ImportActivity} associated with this AyncTask.
|
||||||
|
*
|
||||||
|
* @param importActivity the current {@link ImportActivity}, can be null
|
||||||
|
*/
|
||||||
|
public void setActivity(ImportActivity importActivity) {
|
||||||
|
this.importActivity = importActivity;
|
||||||
|
if (completed && importActivity != null) {
|
||||||
|
importActivity.onAsyncTaskCompleted(success, successCount, totalCount, trackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
if (importActivity != null) {
|
||||||
|
importActivity.showProgressDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
FileUtils fileUtils = new FileUtils();
|
||||||
|
if (!fileUtils.isSdCardAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> files = getFiles();
|
||||||
|
totalCount = files.size();
|
||||||
|
if (totalCount == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < totalCount; i++) {
|
||||||
|
if (isCancelled()) {
|
||||||
|
// If cancelled, return true to show the number of files imported
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
File file = files.get(i);
|
||||||
|
if (importFile(file)) {
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
publishProgress(i + 1, totalCount);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
// Release the wake lock if obtained
|
||||||
|
if (wakeLock != null && wakeLock.isHeld()) {
|
||||||
|
wakeLock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(Integer... values) {
|
||||||
|
if (importActivity != null) {
|
||||||
|
importActivity.setProgressDialogValue(values[0], values[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
success = result;
|
||||||
|
completed = true;
|
||||||
|
if (importActivity != null) {
|
||||||
|
importActivity.onAsyncTaskCompleted(success, successCount, totalCount, trackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a GPX file.
|
||||||
|
*
|
||||||
|
* @param file the file
|
||||||
|
*/
|
||||||
|
private boolean importFile(final File file) {
|
||||||
|
try {
|
||||||
|
long trackIds[] = GpxImporter.importGPXFile(new FileInputStream(file), myTracksProviderUtils);
|
||||||
|
int length = trackIds.length;
|
||||||
|
if (length > 0) {
|
||||||
|
trackId = trackIds[length - 1];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.d(TAG, "file: " + file.getAbsolutePath(), e);
|
||||||
|
return false;
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
Log.d(TAG, "file: " + file.getAbsolutePath(), e);
|
||||||
|
return false;
|
||||||
|
} catch (SAXException e) {
|
||||||
|
Log.d(TAG, "file: " + file.getAbsolutePath(), e);
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.d(TAG, "file: " + file.getAbsolutePath(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of GPX files. If importAll is true, returns a list of GPX files
|
||||||
|
* under the path directory. If importAll is false, returns a list containing
|
||||||
|
* just the path file.
|
||||||
|
*/
|
||||||
|
private List<File> getFiles() {
|
||||||
|
List<File> files = new ArrayList<File>();
|
||||||
|
File file = new File(path);
|
||||||
|
if (importAll) {
|
||||||
|
File[] candidates = file.listFiles();
|
||||||
|
if (candidates != null) {
|
||||||
|
for (File candidate : candidates) {
|
||||||
|
if (!candidate.isDirectory() && candidate.getName().endsWith(".gpx")) {
|
||||||
|
files.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
files.add(file);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -254,18 +254,17 @@ public class TrackList extends ListActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case R.id.tracklist_btn_delete_all: {
|
case R.id.tracklist_btn_delete_all:
|
||||||
showDialog(DIALOG_DELETE_ALL_ID);
|
showDialog(DIALOG_DELETE_ALL_ID);
|
||||||
break;
|
break;
|
||||||
}
|
case R.id.tracklist_btn_export_all:
|
||||||
case R.id.tracklist_btn_export_all: {
|
|
||||||
showDialog(DIALOG_EXPORT_ALL_ID);
|
showDialog(DIALOG_EXPORT_ALL_ID);
|
||||||
break;
|
break;
|
||||||
}
|
case R.id.tracklist_btn_import_all:
|
||||||
case R.id.tracklist_btn_import_all: {
|
Intent intent = new Intent(this, ImportActivity.class)
|
||||||
new ImportAllTracks(this);
|
.putExtra(ImportActivity.EXTRA_IMPORT_ALL, true);
|
||||||
|
startActivity(intent);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 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.io.file;
|
|
||||||
|
|
||||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.ImportAllTracks;
|
|
||||||
import com.google.android.apps.mytracks.util.UriUtils;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An activity that imports a track from a file and displays the track in My Tracks.
|
|
||||||
*
|
|
||||||
* @author Rodrigo Damazio
|
|
||||||
*/
|
|
||||||
public class ImportActivity extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
String action = intent.getAction();
|
|
||||||
Uri data = intent.getData();
|
|
||||||
if (!(Intent.ACTION_VIEW.equals(action) || Intent.ACTION_ATTACH_DATA.equals(action))) {
|
|
||||||
Log.e(TAG, "Received an intent with unsupported action: " + intent);
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UriUtils.isFileUri(data)) {
|
|
||||||
Log.e(TAG, "Received an intent with unsupported data: " + intent);
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String path = data.getPath();
|
|
||||||
Log.i(TAG, "Importing GPX file at " + path);
|
|
||||||
new ImportAllTracks(this, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user