diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index fc695c322..8aa455e91 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -171,6 +171,8 @@ limitations under the License. + + listeners = new ArrayList<>(); + private Track.Id lastTrackId; @Override public void onCreate() { @@ -186,17 +190,26 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand PreferencesUtils.unregister(this, sharedPreferenceChangeListener); + try { voiceExecutor.shutdown(); } finally { 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); @@ -411,6 +424,7 @@ 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); diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java index 284fa2162..bfe3c2292 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java +++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java @@ -1,6 +1,7 @@ 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; @@ -88,6 +89,17 @@ 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; } @Override @@ -97,6 +109,20 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit updateUnits(); updateReset(); updateBluetooth(); + updateExportDirectory(); + setInstantExportPreferenceEnabled(); + } + + 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); } @Override @@ -206,4 +232,5 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit }); } } + } diff --git a/src/main/java/de/dennisguse/opentracks/util/HackUtils.java b/src/main/java/de/dennisguse/opentracks/util/HackUtils.java index 01b5dbeec..aafa12de5 100644 --- a/src/main/java/de/dennisguse/opentracks/util/HackUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/HackUtils.java @@ -16,7 +16,7 @@ public class HackUtils { */ public static void invalidatePreference(@NonNull Preference preference) { boolean isEnabled = preference.isEnabled(); - preference.setEnabled(!isEnabled); - preference.setEnabled(isEnabled); + preference.setVisible(!isEnabled); + preference.setVisible(isEnabled); } } diff --git a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java index 12007d04d..883f561f6 100644 --- a/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/IntentUtils.java @@ -173,4 +173,11 @@ public class IntentUtils { .putExtra(MediaStore.EXTRA_OUTPUT, photoUri); return new Pair<>(intent, photoUri); } + + public static void persistDirectoryAccessPermission(Context context, Intent resultData, Uri directoryUri) { + final int takeFlags = resultData.getFlags() + & (Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + context.getContentResolver().takePersistableUriPermission(directoryUri, takeFlags); + } } diff --git a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java index 187a9d8dc..29e2ccada 100644 --- a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java @@ -19,6 +19,7 @@ package de.dennisguse.opentracks.util; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.net.Uri; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceManager; @@ -337,6 +338,11 @@ public class PreferencesUtils { return getInt(context, R.string.recording_gps_accuracy_key, RECORDING_GPS_ACCURACY); } + 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); + } + public static TrackFileFormat getExportTrackFileFormat(Context context) { final String TRACKFILEFORMAT_NAME_DEFAULT = getString(context, R.string.export_trackfileformat_default, null); String trackFileFormatName = getString(context, R.string.export_trackfileformat_key, TRACKFILEFORMAT_NAME_DEFAULT); @@ -383,4 +389,20 @@ public class PreferencesUtils { } PreferenceManager.setDefaultValues(context, R.xml.settings, readAgain); } + + public static Uri getDefaultExportDirectoryUri(Context context) + { + String singleExportDirectorySettingsKey = getString(context, R.string.settings_default_export_directory_key, null); + if (singleExportDirectorySettingsKey == null) { + return null; + } + return Uri.parse(singleExportDirectorySettingsKey); + } + + public static void setDefaultExportDirectoryUri(Context context, Uri directoryUri) { + setString(context, + R.string.settings_default_export_directory_key, + directoryUri.toString() + ); + } } diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml index 466aada83..4634c8723 100644 --- a/src/main/res/values/settings.xml +++ b/src/main/res/values/settings.xml @@ -26,6 +26,12 @@ bluetoothCyclingSpeedWheelCircumference 2135 + settingsDefaultExportDirectory + false + Instant post-workout export + instantExportEnabled + defaultExportUri + defaultActivity @string/activity_type_unknown diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 626f6c834..42444c06f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -601,4 +601,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 diff --git a/src/main/res/xml/settings.xml b/src/main/res/xml/settings.xml index 056a20b35..e9e68b596 100644 --- a/src/main/res/xml/settings.xml +++ b/src/main/res/xml/settings.xml @@ -151,7 +151,20 @@ limitations under the License. + + + +