mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Show on map: draft via sharing temporary file.
This commit is contained in:
@@ -25,6 +25,7 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.Settings;
|
||||
@@ -46,20 +47,30 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.cursoradapter.widget.ResourceCursorAdapter;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.app.LoaderManager.LoaderCallbacks;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
import androidx.loader.content.Loader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import de.dennisguse.opentracks.content.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.content.Track;
|
||||
import de.dennisguse.opentracks.content.TracksColumns;
|
||||
import de.dennisguse.opentracks.fragments.ConfirmDeleteDialogFragment;
|
||||
import de.dennisguse.opentracks.io.file.TrackFileFormat;
|
||||
import de.dennisguse.opentracks.io.file.exporter.FileTrackExporter;
|
||||
import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
|
||||
import de.dennisguse.opentracks.services.ITrackRecordingService;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
|
||||
import de.dennisguse.opentracks.settings.SettingsActivity;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.ListItemUtils;
|
||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||
@@ -107,8 +118,7 @@ public class TrackListActivity extends AbstractTrackActivity implements ConfirmD
|
||||
private boolean metricUnits = true;
|
||||
private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
|
||||
// Callback when an item is selected in the contextual action mode
|
||||
private final ContextualActionModeCallback
|
||||
contextualActionModeCallback = new ContextualActionModeCallback() {
|
||||
private final ContextualActionModeCallback contextualActionModeCallback = new ContextualActionModeCallback() {
|
||||
|
||||
@Override
|
||||
public void onPrepare(Menu menu, int[] positions, long[] ids, boolean showSelectAll) {
|
||||
@@ -116,7 +126,6 @@ public class TrackListActivity extends AbstractTrackActivity implements ConfirmD
|
||||
boolean isSingleSelection = ids.length == 1;
|
||||
|
||||
menu.findItem(R.id.list_context_menu_share).setVisible(!isRecording && isSingleSelection);
|
||||
menu.findItem(R.id.list_context_menu_show_on_map).setVisible(false);
|
||||
menu.findItem(R.id.list_context_menu_edit).setVisible(isSingleSelection);
|
||||
menu.findItem(R.id.list_context_menu_select_all).setVisible(showSelectAll);
|
||||
}
|
||||
@@ -128,7 +137,7 @@ public class TrackListActivity extends AbstractTrackActivity implements ConfirmD
|
||||
};
|
||||
private boolean recordingTrackPaused = PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT;
|
||||
/*
|
||||
* Note that sharedPreferenceChangeListenr cannot be an anonymous inner class.
|
||||
* Note that sharedPreferenceChangeListener cannot be an anonymous inner class.
|
||||
* Anonymous inner class will get garbage collected.
|
||||
*/
|
||||
private final OnSharedPreferenceChangeListener
|
||||
@@ -556,6 +565,59 @@ public class TrackListActivity extends AbstractTrackActivity implements ConfirmD
|
||||
bindChangedCallback.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save tracks in one file and send an intent to show it with a map application.
|
||||
* TODO: Exported file is not deleted automatically.
|
||||
*
|
||||
* @param trackIds
|
||||
*/
|
||||
private void showOnExternalMap(long[] trackIds) {
|
||||
if (trackIds.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Track[] tracks = new Track[trackIds.length];
|
||||
for (int i = 0; i < trackIds.length; i++) {
|
||||
tracks[i] = contentProviderUtils.getTrack(trackIds[i]);
|
||||
}
|
||||
|
||||
TrackFileFormat trackFileFormat = TrackFileFormat.KML;
|
||||
TrackExporter trackExporter = new FileTrackExporter(contentProviderUtils, tracks,
|
||||
trackFileFormat.newTrackWriter(this, tracks.length > 1), null);
|
||||
|
||||
File directory = new File(FileUtils.getPath(trackFileFormat.getExtension()));
|
||||
if (!FileUtils.ensureDirectoryExists(directory)) {
|
||||
Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
String fileName = FileUtils.buildUniqueFileName(directory, tracks[0].getName(), trackFileFormat.getExtension());
|
||||
File file = new File(directory, fileName);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
if (trackExporter.writeTrack(fileOutputStream)) {
|
||||
Uri fileUri = FileProvider.getUriForFile(this, FileUtils.FILEPROVIDER, file);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(android.content.Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(fileUri, "application/vnd.google-earth.kml+xml");
|
||||
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
if (!file.delete()) {
|
||||
Log.d(TAG, "Unable to delete file");
|
||||
}
|
||||
Log.e(TAG, "Unable to export track");
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(TAG, "Unable to open file " + file.getName(), e);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Unable to close file output stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a context item selection.
|
||||
*
|
||||
@@ -565,6 +627,9 @@ public class TrackListActivity extends AbstractTrackActivity implements ConfirmD
|
||||
*/
|
||||
private boolean handleContextItem(int itemId, long[] trackIds) {
|
||||
switch (itemId) {
|
||||
case R.id.list_context_menu_show_on_map:
|
||||
showOnExternalMap(trackIds);
|
||||
return true;
|
||||
case R.id.list_context_menu_share:
|
||||
//TODO
|
||||
Log.e(TAG, "Not implemented");
|
||||
|
||||
@@ -41,6 +41,7 @@ import de.dennisguse.opentracks.util.SystemUtils;
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
//TODO Make independent from ExportActivity?
|
||||
public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
private static final String TAG = SaveAsyncTask.class.getSimpleName();
|
||||
@@ -144,7 +145,7 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves tracks to one file.
|
||||
* Saves tracks to one file (uses first track to determine the filename).
|
||||
*
|
||||
* @param tracks the tracks
|
||||
*/
|
||||
@@ -153,7 +154,6 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
Track track = tracks[0];
|
||||
FileTrackExporter fileTrackExporter = new FileTrackExporter(contentProviderUtils, tracks,
|
||||
trackFileFormat.newTrackWriter(context, tracks.length > 1),
|
||||
new TrackExporterListener() {
|
||||
@@ -169,6 +169,7 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
String extension = useKmz ? KmzTrackExporter.KMZ_EXTENSION : trackFileFormat.getExtension();
|
||||
TrackExporter trackExporter = useKmz ? new KmzTrackExporter(contentProviderUtils, fileTrackExporter, tracks) : fileTrackExporter;
|
||||
|
||||
Track track = tracks[0];
|
||||
String fileName = FileUtils.buildUniqueFileName(directory, track.getName(), extension);
|
||||
File file = new File(directory, fileName);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user