diff --git a/doc/activities.txt b/doc/activities.txt
index 3536f7c73..f385ac47a 100644
--- a/doc/activities.txt
+++ b/doc/activities.txt
@@ -47,8 +47,9 @@ MarkerDetailActivity --> CoordinateOnMapIntent : URI
SettingsActivity --> AboutActivity
SettingsActivity --> HelpActivity
SettingsActivity --> ExportActivity
-SettingsActivity --> DirectoryChooserActivity
-SettingsActivity --> DirectoryChooserActivity
+SettingsActivity --> DirectoryChooserActivity$ImportDirectoryChooserActivity
+SettingsActivity --> DirectoryChooserActivity$ExportDirectoryChooserActivity
+SettingsActivity --> DirectoryChooserActivity$DefaultTrackExportDirectoryChooserActivity
DirectoryChooserActivity$ImportDirectoryChooserActivity --> ImportActivity
DirectoryChooserActivity$ExportDirectoryChooserActivity --> ExportActivity
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 8aa455e91..81d7cf1ea 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -152,6 +152,7 @@ limitations under the License.
+
-
-
listeners = new ArrayList<>();
- private Track.Id lastTrackId;
@Override
public void onCreate() {
@@ -197,19 +194,11 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
voiceExecutor = null;
}
- if (PreferencesUtils.shouldInstantExportAfterWorkout(getApplicationContext())) {
- TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(this);
-
- Uri directoryUri = PreferencesUtils.getDefaultExportDirectoryUri(getApplicationContext());
- exportTrackToUri(directoryUri, getApplicationContext(), contentProviderUtils, trackFileFormat, lastTrackId);
- }
-
contentProviderUtils = null;
binder.detachFromService();
binder = null;
-
// This should be the next to last operation
wakeLock = SystemUtils.releaseWakeLock(wakeLock);
@@ -424,7 +413,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
// Need to remember the recordingTrackId before setting it to -1L
Track.Id trackId = recordingTrackId;
- lastTrackId = recordingTrackId;
boolean wasPaused = recordingTrackPaused;
updateRecordingState(null, true);
@@ -442,6 +430,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
updateTrackTotalTime(track);
}
}
+
+ ExportUtils.postWorkoutExport(this, track);
+
endRecording(true);
}
diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
index bfe3c2292..e22e19f8a 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
@@ -1,13 +1,13 @@
package de.dennisguse.opentracks.settings;
import android.content.SharedPreferences;
-import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
+import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.DialogFragment;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
@@ -89,17 +89,13 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
setExportTrackFileFormatOptions();
setWheelCircumferenceInputFilter();
- Preference instantExportDirectoryPreference = findPreference(getString(R.string.preference_key_default_export_uri));
- if (instantExportDirectoryPreference != null) {
- instantExportDirectoryPreference.setSummaryProvider(preference -> {
- Uri uri = PreferencesUtils.getDefaultExportDirectoryUri(getContext());
- return uri != null ? uri.getPath() : getString(R.string.summay_default_export_directory_not_set_yet);
- });
- }
- }
- private boolean isDefaultExportDirectorySet() {
- return PreferencesUtils.getDefaultExportDirectoryUri(getContext()) != null;
+ Preference instantExportDirectoryPreference = findPreference(getString(R.string.settings_default_export_directory_key));
+ instantExportDirectoryPreference.setSummaryProvider(preference -> {
+ DocumentFile directory = PreferencesUtils.getDefaultExportDirectoryUri(getContext());
+ //Use same value for not set as Androidx ListPreference and EditTextPreference
+ return directory != null ? directory.getName() : getString(R.string.not_set);
+ });
}
@Override
@@ -109,20 +105,13 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
updateUnits();
updateReset();
updateBluetooth();
- updateExportDirectory();
- setInstantExportPreferenceEnabled();
+
+ updatePostWorkoutExport();
}
- private void setInstantExportPreferenceEnabled() {
- Preference instantExportEnabledPreference = findPreference("instantExportEnabled");
- assert instantExportEnabledPreference != null;
- instantExportEnabledPreference.setEnabled(isDefaultExportDirectorySet());
- }
-
- private void updateExportDirectory() {
- Preference defaultExportDirectoryPreference = findPreference("defaultExportUri");
- assert defaultExportDirectoryPreference != null;
- HackUtils.invalidatePreference(defaultExportDirectoryPreference);
+ private void updatePostWorkoutExport() {
+ Preference instantExportEnabledPreference = findPreference(getString(R.string.post_workout_export_enabled_key));
+ instantExportEnabledPreference.setEnabled(PreferencesUtils.isDefaultExportDirectoryUri(getContext()));
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/util/ExportUtils.java b/src/main/java/de/dennisguse/opentracks/util/ExportUtils.java
new file mode 100644
index 000000000..2e1ab83fc
--- /dev/null
+++ b/src/main/java/de/dennisguse/opentracks/util/ExportUtils.java
@@ -0,0 +1,65 @@
+package de.dennisguse.opentracks.util;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.documentfile.provider.DocumentFile;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import de.dennisguse.opentracks.content.data.Track;
+import de.dennisguse.opentracks.io.file.TrackFileFormat;
+import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
+
+public class ExportUtils {
+
+ private static final String TAG = ExportUtils.class.getSimpleName();
+
+ public static void postWorkoutExport(Context context, Track track) {
+ if (PreferencesUtils.shouldInstantExportAfterWorkout(context)) {
+ TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat(context);
+ DocumentFile directory = PreferencesUtils.getDefaultExportDirectoryUri(context);
+
+ exportTrack(context, trackFileFormat, directory, track);
+ }
+ }
+
+ public static boolean exportTrack(Context context, TrackFileFormat trackFileFormat, DocumentFile directory, Track track) {
+ TrackExporter trackExporter = trackFileFormat.newTrackExporter(context);
+
+ DocumentFile exportDocumentFile = ExportUtils.getExportDocumentFile(track.getId(), trackFileFormat.getExtension(), directory, trackFileFormat.getMimeType());
+
+ try (OutputStream outputStream = context.getContentResolver().openOutputStream(exportDocumentFile.getUri())) {
+ if (trackExporter.writeTrack(track, outputStream)) {
+ return true;
+ } else {
+ if (!exportDocumentFile.delete()) {
+ Log.e(TAG, "Unable to delete exportDocumentFile");
+ }
+ Log.e(TAG, "Unable to export track");
+ return false;
+ }
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Unable to open exportDocumentFile " + exportDocumentFile.getName(), e);
+ return false;
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to close exportDocumentFile output stream", e);
+ return false;
+ }
+ }
+
+ public static DocumentFile getExportDocumentFile(Track.Id trackId, String trackFileFormatExtension, DocumentFile directory, String mimeType) {
+ String fileName = getExportFileNameByTrackId(trackId, trackFileFormatExtension);
+ DocumentFile file = directory.findFile(fileName);
+ if (file == null) {
+ file = directory.createFile(mimeType, fileName);
+ }
+ return file;
+ }
+
+ private static String getExportFileNameByTrackId(Track.Id trackId, String trackFileFormatExtension) {
+ return trackId.getId() + "." + trackFileFormatExtension;
+ }
+}
diff --git a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
index 29e2ccada..0f0d037d2 100644
--- a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
@@ -20,8 +20,10 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
+import androidx.documentfile.provider.DocumentFile;
import androidx.preference.PreferenceManager;
import de.dennisguse.opentracks.R;
@@ -35,6 +37,8 @@ import de.dennisguse.opentracks.io.file.TrackFileFormat;
*/
public class PreferencesUtils {
+ private final static String TAG = PreferencesUtils.class.getSimpleName();
+
private PreferencesUtils() {
}
@@ -339,8 +343,8 @@ public class PreferencesUtils {
}
public static boolean shouldInstantExportAfterWorkout(Context context) {
- final boolean INSTANT_POST_WORKOUT_EXPORT_DEFAULT = context.getResources().getBoolean(R.bool.instant_export_enabled_default);
- return getBoolean(context, R.string.instant_export_enabled_key, INSTANT_POST_WORKOUT_EXPORT_DEFAULT);
+ final boolean INSTANT_POST_WORKOUT_EXPORT_DEFAULT = context.getResources().getBoolean(R.bool.post_workout_export_enabled_default);
+ return getBoolean(context, R.string.post_workout_export_enabled_key, INSTANT_POST_WORKOUT_EXPORT_DEFAULT);
}
public static TrackFileFormat getExportTrackFileFormat(Context context) {
@@ -390,19 +394,25 @@ public class PreferencesUtils {
PreferenceManager.setDefaultValues(context, R.xml.settings, readAgain);
}
- public static Uri getDefaultExportDirectoryUri(Context context)
- {
+ public static DocumentFile getDefaultExportDirectoryUri(Context context) {
String singleExportDirectorySettingsKey = getString(context, R.string.settings_default_export_directory_key, null);
if (singleExportDirectorySettingsKey == null) {
return null;
}
- return Uri.parse(singleExportDirectorySettingsKey);
+ try {
+ return DocumentFile.fromTreeUri(context, Uri.parse(singleExportDirectorySettingsKey));
+ } catch (Exception e) {
+ Log.w(TAG, "Could not decode default export directory: " + e.getMessage());
+ }
+ return null;
}
public static void setDefaultExportDirectoryUri(Context context, Uri directoryUri) {
- setString(context,
- R.string.settings_default_export_directory_key,
- directoryUri.toString()
- );
+ String value = directoryUri != null ? directoryUri.toString() : null;
+ setString(context, R.string.settings_default_export_directory_key, value);
+ }
+
+ public static boolean isDefaultExportDirectoryUri(Context context) {
+ return getDefaultExportDirectoryUri(context) != null;
}
}
diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml
index 4634c8723..4b3b571aa 100644
--- a/src/main/res/values/settings.xml
+++ b/src/main/res/values/settings.xml
@@ -27,10 +27,8 @@
2135
settingsDefaultExportDirectory
- false
- Instant post-workout export
- instantExportEnabled
- defaultExportUri
+ instantExportEnabled
+ false
defaultActivity
@string/activity_type_unknown
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 42444c06f..0534380ce 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -602,8 +602,9 @@ limitations under the License.
Hold to stop recording
Hold to pause recording
Last track exported
- Export track to storage after recording finished
- Set track export directory
- defaultExportUri
- not set yet
+
+ Export track to storage after recording is finished
+ Instant post-workout export
+
+ Track export directory
diff --git a/src/main/res/xml/settings.xml b/src/main/res/xml/settings.xml
index e9e68b596..8e23c55ab 100644
--- a/src/main/res/xml/settings.xml
+++ b/src/main/res/xml/settings.xml
@@ -52,11 +52,11 @@ limitations under the License.
android:key="@string/stats_show_coordinate_key"
android:title="@string/settings_stats_coordinate" />
@@ -151,22 +151,21 @@ limitations under the License.
+
+
+
-
-
-