diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 2b3327011..10b7451b4 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -395,11 +395,6 @@ limitations under the License.
android:icon="@drawable/ic_logo_color_24dp"
android:label="@string/recording_service" />
-
-
directoryFiles;
private int trackExportSuccessCount;
@@ -161,8 +164,6 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
DocumentFile documentFile = DocumentFile.fromTreeUri(this, directoryUri);
String directoryDisplayName = FileUtils.getPath(documentFile);
- resultReceiver = new ExportService.ExportServiceResultReceiver(new Handler(), this);
-
if (savedInstanceState == null) {
autoConflict = ConflictResolutionStrategy.CONFLICT_NONE;
setProgress();
@@ -231,19 +232,45 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
if (fileExists && conflictResolution == ConflictResolutionStrategy.CONFLICT_NONE) {
conflict(exportTask);
- } else if (fileExists && conflictResolution == ConflictResolutionStrategy.CONFLICT_SKIP) {
+ return;
+ }
+ if (fileExists && conflictResolution == ConflictResolutionStrategy.CONFLICT_SKIP) {
trackExportSkippedCount++;
nextExport(exportTask);
- } else {
- ExportService.enqueue(this, resultReceiver, exportTask, directoryUri);
+ return;
}
+
+ WorkManager workManager = WorkManager.getInstance(this);
+ WorkRequest exportRequest = new OneTimeWorkRequest.Builder(ExportWorker.class)
+ .setInputData(new Data.Builder()
+ .putLongArray(ExportWorker.TRACKIDS_KEY, exportTask.getTrackIds().stream().mapToLong(Track.Id::id).toArray())
+ .putString(ExportWorker.DIRECTORY_URI_KEY, directoryUri.toString())
+ .putString(ExportWorker.TRACKFILEFORMAT_KEY, exportTask.getTrackFileFormat().toString())
+ .putString(ExportWorker.FILENAME_KEY, exportTask.getFilename())
+ .build())
+ .build();
+
+ workManager
+ .getWorkInfoByIdLiveData(exportRequest.getId())
+ .observe(this, workInfo -> {
+ if (workInfo != null) {
+ WorkInfo.State state = workInfo.getState();
+ switch (state) {
+ case SUCCEEDED -> onExportSuccess(exportTask);
+ case FAILED ->
+ onExportError(exportTask, workInfo.getOutputData().getString(ExportWorker.RESULT_EXPORT_ERROR_MESSAGE_KEY));
+ }
+ }
+ });
+
+ workManager.enqueue(exportRequest);
}
private void export(ExportTask exportTask) {
export(exportTask, autoConflict);
}
- @Deprecated //TODO Check should be done in ExportService
+ @Deprecated //TODO Check should be done in ExportWorker
private boolean exportFileExists(ExportTask exportTask) {
String filename;
if (exportTask.isMultiExport()) {
@@ -314,7 +341,6 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
}
}
- @Override
public void onExportSuccess(ExportTask exportTask) {
if (exportFileExists(exportTask)) {
trackExportOverwrittenCount++;
@@ -325,7 +351,6 @@ public class ExportActivity extends AppCompatActivity implements ExportService.E
nextExport(exportTask);
}
- @Override
public void onExportError(ExportTask exportTask, String errorMessage) {
trackExportErrorCount++;
String name;
diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportService.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportService.java
deleted file mode 100644
index 871a3cb53..000000000
--- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportService.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package de.dennisguse.opentracks.io.file.exporter;
-
-import android.app.job.JobService;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.core.app.JobIntentService;
-import androidx.documentfile.provider.DocumentFile;
-
-import de.dennisguse.opentracks.R;
-import de.dennisguse.opentracks.util.ExportUtils;
-
-public class ExportService extends JobIntentService {
-
- private static final String TAG = ExportService.class.getSimpleName();
-
- private static final int JOB_ID = 1;
-
- private static final String EXTRA_RECEIVER = "extra_receiver";
- private static final String EXTRA_EXPORT_TASK = "export_task";
- private static final String EXTRA_DIRECTORY_URI = "extra_directory_uri";
-
- public static void enqueue(Context context, ExportServiceResultReceiver receiver, ExportTask exportTask, Uri directoryUri) {
- Intent intent = new Intent(context, JobService.class);
- intent.putExtra(EXTRA_RECEIVER, receiver);
- intent.putExtra(EXTRA_EXPORT_TASK, exportTask);
- intent.putExtra(EXTRA_DIRECTORY_URI, directoryUri);
- enqueueWork(context, ExportService.class, JOB_ID, intent);
- }
-
- @Override
- protected void onHandleWork(@NonNull Intent intent) {
- // Get all data.
- ResultReceiver resultReceiver = intent.getParcelableExtra(EXTRA_RECEIVER);
- ExportTask exportTask = intent.getParcelableExtra(EXTRA_EXPORT_TASK);
- Uri directoryUri = intent.getParcelableExtra(EXTRA_DIRECTORY_URI);
-
- // Prepare resultCode and bundle to send to the receiver.
- Bundle bundle = new Bundle();
- bundle.putParcelable(ExportServiceResultReceiver.RESULT_EXTRA_EXPORT_TASK, exportTask);
-
- // Build directory file.
- DocumentFile directoryFile = DocumentFile.fromTreeUri(this, directoryUri);
- if (directoryFile == null || !directoryFile.canWrite()) {
- bundle.putString(ExportServiceResultReceiver.EXTRA_EXPORT_ERROR_MESSAGE, getString(R.string.export_cannot_write_to_dir) + ": " + directoryFile);
- resultReceiver.send(ExportServiceResultReceiver.RESULT_CODE_ERROR, bundle);
- return;
- }
-
- // Export and send result
- try {
- ExportUtils.exportTrack(this, directoryFile, exportTask);
- resultReceiver.send(ExportServiceResultReceiver.RESULT_CODE_SUCCESS, bundle);
- } catch (Exception e) {
- Log.e(TAG, "Export failed: " + e);
- e.printStackTrace(); //TODO Remove
-
- bundle.putString(ExportServiceResultReceiver.EXTRA_EXPORT_ERROR_MESSAGE, e.getMessage());
- resultReceiver.send(ExportServiceResultReceiver.RESULT_CODE_ERROR, bundle);
- }
- }
-
- public static class ExportServiceResultReceiver extends ResultReceiver {
-
- public static final int RESULT_CODE_SUCCESS = 1;
- public static final int RESULT_CODE_ERROR = 0;
-
- public static final String RESULT_EXTRA_EXPORT_TASK = "result_extra_export_task";
-
- public static final String EXTRA_EXPORT_ERROR_MESSAGE = "extra_export_error_message";
-
- private final Receiver receiver;
-
- public ExportServiceResultReceiver(Handler handler, @NonNull Receiver receiver) {
- super(handler);
- this.receiver = receiver;
- }
-
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- ExportTask exportTask = resultData.getParcelable(RESULT_EXTRA_EXPORT_TASK);
- switch (resultCode) {
- case RESULT_CODE_SUCCESS -> receiver.onExportSuccess(exportTask);
- case RESULT_CODE_ERROR -> receiver.onExportError(exportTask, resultData.getString(EXTRA_EXPORT_ERROR_MESSAGE));
- default -> throw new RuntimeException("Unknown resultCode.");
- }
- }
-
- public interface Receiver {
- default void onExportSuccess(ExportTask exportTask) {
- }
-
- default void onExportError(ExportTask exportTask, String errorMessage) {
- }
- }
- }
-}
diff --git a/src/main/java/de/dennisguse/opentracks/util/ExportUtils.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportUtils.java
similarity index 60%
rename from src/main/java/de/dennisguse/opentracks/util/ExportUtils.java
rename to src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportUtils.java
index 552ee12d6..d9c875aea 100644
--- a/src/main/java/de/dennisguse/opentracks/util/ExportUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportUtils.java
@@ -1,15 +1,21 @@
-package de.dennisguse.opentracks.util;
+package de.dennisguse.opentracks.io.file.exporter;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Handler;
import android.provider.DocumentsContract;
import android.util.Log;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.documentfile.provider.DocumentFile;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkInfo;
+import androidx.work.WorkManager;
+import androidx.work.WorkRequest;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -22,36 +28,81 @@ import de.dennisguse.opentracks.data.ContentProviderUtils;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.io.file.TrackFilenameGenerator;
-import de.dennisguse.opentracks.io.file.exporter.ExportService;
-import de.dennisguse.opentracks.io.file.exporter.ExportService.ExportServiceResultReceiver;
-import de.dennisguse.opentracks.io.file.exporter.ExportTask;
-import de.dennisguse.opentracks.io.file.exporter.TrackExporter;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.settings.SettingsActivity;
+import de.dennisguse.opentracks.util.IntentUtils;
public class ExportUtils {
private static final String TAG = ExportUtils.class.getSimpleName();
- public static void postWorkoutExport(Context context, Track.Id trackId) {
+ public static void postWorkoutExport(AppCompatActivity context, Track.Id trackId) {
if (PreferencesUtils.shouldInstantExportAfterWorkout()) {
TrackFileFormat trackFileFormat = PreferencesUtils.getExportTrackFileFormat();
DocumentFile directory = IntentUtils.toDocumentFile(context, PreferencesUtils.getDefaultExportDirectoryUri());
- ExportServiceResultReceiver resultReceiver = new ExportServiceResultReceiver(new Handler(), new ExportServiceResultReceiver.Receiver() {
- @Override
- public void onExportError(ExportTask unused, String errorMessage) {
- Intent intent = new Intent(context, SettingsActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(SettingsActivity.EXTRAS_EXPORT_ERROR_MESSAGE, errorMessage);
- context.startActivity(intent);
- }
- });
+ WorkManager workManager = WorkManager.getInstance(context);
+ WorkRequest exportRequest = new OneTimeWorkRequest.Builder(ExportWorker.class)
+ .setInputData(new Data.Builder()
+ .putLongArray(ExportWorker.TRACKIDS_KEY, new long[]{trackId.id()})
+ .putString(ExportWorker.DIRECTORY_URI_KEY, directory.toString())
+ .putString(ExportWorker.TRACKFILEFORMAT_KEY, trackFileFormat.toString())
+ .putString(ExportWorker.FILENAME_KEY, null)
+ .build())
+ .build();
- ExportService.enqueue(context, resultReceiver, new ExportTask(null, trackFileFormat, List.of(trackId)), directory.getUri());
+ workManager
+ .getWorkInfoByIdLiveData(exportRequest.getId())
+ .observe(context, workInfo -> {
+ if (workInfo != null) {
+ if (workInfo.getState() == WorkInfo.State.FAILED) {
+ Intent intent = new Intent(context, SettingsActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(SettingsActivity.EXTRAS_EXPORT_ERROR_MESSAGE, workInfo.getProgress().getString(ExportWorker.RESULT_EXPORT_ERROR_MESSAGE_KEY));
+ context.startActivity(intent);
+ }
+ }
+ });
+
+ workManager.enqueue(exportRequest);
}
}
+ public static void exportTrack(Context context, DocumentFile directory, @Nullable String filenameForMultiple, TrackFileFormat trackFileFormat, List trackIds) {
+
+ ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
+ List