diff --git a/app/build.gradle b/app/build.gradle
index 96cfdac..c967b2e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -82,6 +82,9 @@ dependencies {
implementation 'stax:stax-api:1.0.1'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
+ // File Utils
+ implementation 'commons-io:commons-io:2.6'
+
// Upload to OSM
implementation('de.westnordost:osmapi-traces:1.0')
configurations {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c6c3c40..79648e4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,6 +27,7 @@
+
{
try{
String file= getFilesDir().getAbsolutePath() + "/shared/backup.ftb";
- if (!new File(file).getParentFile().mkdirs()) {
+ File parent = new File(file).getParentFile();
+ if (!parent.exists() && !parent.mkdirs()) {
throw new IOException("Cannot write");
}
Uri uri= FileProvider.getUriForFile(getBaseContext(), "de.tadris.fitness.fileprovider", new File(file));
@@ -125,7 +131,7 @@ public class SettingsActivity extends FitoTrackSettingsActivity {
mHandler.post(() -> {
dialogController.cancel();
- shareFile(uri);
+ FileUtils.saveOrShareFile(this, uri, "ftb");
});
}catch (Exception e){
e.printStackTrace();
diff --git a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java
index 02cdb4a..d336847 100644
--- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java
+++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java
@@ -48,6 +48,7 @@ import de.tadris.fitness.data.WorkoutSample;
import de.tadris.fitness.osm.OAuthAuthentication;
import de.tadris.fitness.osm.OsmTraceUploader;
import de.tadris.fitness.util.DialogUtils;
+import de.tadris.fitness.util.FileUtils;
import de.tadris.fitness.util.gpx.GpxExporter;
import de.tadris.fitness.util.unit.UnitUtils;
import de.tadris.fitness.view.ProgressDialogController;
@@ -202,20 +203,25 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils.
}
private void exportToGpx(){
+ if (!hasStoragePermission()) {
+ requestStoragePermissions();
+ return;
+ }
ProgressDialogController dialogController= new ProgressDialogController(this, getString(R.string.exporting));
dialogController.setIndeterminate(true);
dialogController.show();
new Thread(() -> {
try{
String file= getFilesDir().getAbsolutePath() + "/shared/workout.gpx";
- if (!new File(file).getParentFile().mkdirs()) {
+ File parent = new File(file).getParentFile();
+ if (!parent.exists() && !parent.mkdirs()) {
throw new IOException("Cannot write to " + file);
}
Uri uri= FileProvider.getUriForFile(getBaseContext(), "de.tadris.fitness.fileprovider", new File(file));
GpxExporter.exportWorkout(getBaseContext(), workout, new File(file));
dialogController.cancel();
- mHandler.post(() -> shareFile(uri));
+ mHandler.post(() -> FileUtils.saveOrShareFile(this, uri, "gpx"));
}catch (Exception e){
e.printStackTrace();
mHandler.post(() -> showErrorDialog(e, R.string.error, R.string.errorGpxExportFailed));
diff --git a/app/src/main/java/de/tadris/fitness/export/BackupController.java b/app/src/main/java/de/tadris/fitness/export/BackupController.java
index dd7b7c1..546ffe3 100644
--- a/app/src/main/java/de/tadris/fitness/export/BackupController.java
+++ b/app/src/main/java/de/tadris/fitness/export/BackupController.java
@@ -31,7 +31,6 @@ import java.util.Arrays;
import de.tadris.fitness.Instance;
import de.tadris.fitness.R;
import de.tadris.fitness.data.AppDatabase;
-import de.tadris.fitness.data.UserPreferences;
import de.tadris.fitness.util.unit.UnitUtils;
public class BackupController {
@@ -41,7 +40,6 @@ public class BackupController {
private final Context context;
private final File output;
private final ExportStatusListener listener;
- private UserPreferences preferences;
private AppDatabase database;
private FitoTrackDataContainer dataContainer;
@@ -55,10 +53,6 @@ public class BackupController {
public void exportData() throws IOException {
listener.onStatusChanged(0, context.getString(R.string.initialising));
init();
- listener.onStatusChanged(10, context.getString(R.string.preferences));
- newContainer();
-
- saveSettingsToContainer();
listener.onStatusChanged(20, context.getString(R.string.workouts));
saveWorkoutsToContainer();
listener.onStatusChanged(40, context.getString(R.string.locationData));
@@ -69,32 +63,24 @@ public class BackupController {
}
private void init(){
- preferences= Instance.getInstance(context).userPreferences;
database= Instance.getInstance(context).db;
UnitUtils.setUnit(context); // Ensure unit system is correct
+ newContainer();
}
private void newContainer(){
dataContainer= new FitoTrackDataContainer();
- dataContainer.version= VERSION;
- dataContainer.workouts= new ArrayList<>();
- dataContainer.samples= new ArrayList<>();
- }
-
- private void saveSettingsToContainer(){
- FitoTrackSettings settings= new FitoTrackSettings();
- settings.weight= preferences.getUserWeight();
- settings.mapStyle= preferences.getMapStyle();
- settings.preferredUnitSystem= String.valueOf(UnitUtils.CHOSEN_SYSTEM.getId());
- dataContainer.settings= settings;
+ dataContainer.setVersion(VERSION);
+ dataContainer.setWorkouts(new ArrayList<>());
+ dataContainer.setSamples(new ArrayList<>());
}
private void saveWorkoutsToContainer(){
- dataContainer.workouts.addAll(Arrays.asList(database.workoutDao().getWorkouts()));
+ dataContainer.getWorkouts().addAll(Arrays.asList(database.workoutDao().getWorkouts()));
}
private void saveSamplesToContainer(){
- dataContainer.samples.addAll(Arrays.asList(database.workoutDao().getSamples()));
+ dataContainer.getSamples().addAll(Arrays.asList(database.workoutDao().getSamples()));
}
private void writeContainerToOutputFile() throws IOException {
diff --git a/app/src/main/java/de/tadris/fitness/export/FitoTrackDataContainer.java b/app/src/main/java/de/tadris/fitness/export/FitoTrackDataContainer.java
index 2e25eac..fad4d84 100644
--- a/app/src/main/java/de/tadris/fitness/export/FitoTrackDataContainer.java
+++ b/app/src/main/java/de/tadris/fitness/export/FitoTrackDataContainer.java
@@ -31,18 +31,16 @@ import de.tadris.fitness.data.WorkoutSample;
@JsonIgnoreProperties(ignoreUnknown = true)
class FitoTrackDataContainer {
- int version;
- List workouts;
- List samples;
- FitoTrackSettings settings;
+ private int version;
+ private List workouts;
+ private List samples;
public FitoTrackDataContainer(){}
- public FitoTrackDataContainer(int version, List workouts, List samples, FitoTrackSettings settings) {
+ public FitoTrackDataContainer(int version, List workouts, List samples) {
this.version = version;
this.workouts = workouts;
this.samples = samples;
- this.settings = settings;
}
public int getVersion() {
@@ -69,11 +67,5 @@ class FitoTrackDataContainer {
this.samples = samples;
}
- public FitoTrackSettings getSettings() {
- return settings;
- }
- public void setSettings(FitoTrackSettings settings) {
- this.settings = settings;
- }
}
diff --git a/app/src/main/java/de/tadris/fitness/export/FitoTrackSettings.java b/app/src/main/java/de/tadris/fitness/export/FitoTrackSettings.java
deleted file mode 100644
index 44b50b2..0000000
--- a/app/src/main/java/de/tadris/fitness/export/FitoTrackSettings.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2019 Jannis Scheibe
- *
- * This file is part of FitoTrack
- *
- * FitoTrack is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * FitoTrack is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.tadris.fitness.export;
-
-public class FitoTrackSettings {
-
- String preferredUnitSystem;
- int weight;
- String mapStyle;
-
- public FitoTrackSettings(){}
-
- public FitoTrackSettings(String preferredUnitSystem, int weight, String mapStyle) {
- this.preferredUnitSystem = preferredUnitSystem;
- this.weight = weight;
- this.mapStyle = mapStyle;
- }
-
- public String getPreferredUnitSystem() {
- return preferredUnitSystem;
- }
-
- public void setPreferredUnitSystem(String preferredUnitSystem) {
- this.preferredUnitSystem = preferredUnitSystem;
- }
-
- public int getWeight() {
- return weight;
- }
-
- public void setWeight(int weight) {
- this.weight = weight;
- }
-
- public String getMapStyle() {
- return mapStyle;
- }
-
- public void setMapStyle(String mapStyle) {
- this.mapStyle = mapStyle;
- }
-}
diff --git a/app/src/main/java/de/tadris/fitness/export/RestoreController.java b/app/src/main/java/de/tadris/fitness/export/RestoreController.java
index 1ca0bda..49828ce 100644
--- a/app/src/main/java/de/tadris/fitness/export/RestoreController.java
+++ b/app/src/main/java/de/tadris/fitness/export/RestoreController.java
@@ -19,10 +19,8 @@
package de.tadris.fitness.export;
-import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
-import android.preference.PreferenceManager;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
@@ -54,9 +52,6 @@ public class RestoreController {
listener.onStatusChanged(0, context.getString(R.string.loadingFile));
loadDataFromFile();
checkVersion();
- listener.onStatusChanged(40, context.getString(R.string.preferences));
- restoreSettings();
-
restoreDatabase();
listener.onStatusChanged(100, context.getString(R.string.finished));
}
@@ -68,21 +63,11 @@ public class RestoreController {
}
private void checkVersion() throws UnsupportedVersionException {
- if(dataContainer.version != 1){
- throw new UnsupportedVersionException("Version Code" + dataContainer.version + " is unsupported!");
+ if (dataContainer.getVersion() != 1) {
+ throw new UnsupportedVersionException("Version Code" + dataContainer.getVersion() + " is unsupported!");
}
}
- @SuppressLint("ApplySharedPref")
- private void restoreSettings(){
- PreferenceManager.getDefaultSharedPreferences(context)
- .edit().clear()
- .putInt("weight", dataContainer.settings.weight)
- .putString("unitSystem", dataContainer.settings.preferredUnitSystem)
- .putBoolean("firstStart", false).putString("mapStyle", dataContainer.settings.mapStyle)
- .commit();
- }
-
private void restoreDatabase(){
database.runInTransaction(() -> {
resetDatabase();
@@ -97,8 +82,8 @@ public class RestoreController {
private void restoreWorkouts(){
listener.onStatusChanged(60, context.getString(R.string.workouts));
- if(dataContainer.workouts != null){
- for(Workout workout : dataContainer.workouts){
+ if (dataContainer.getWorkouts() != null) {
+ for (Workout workout : dataContainer.getWorkouts()) {
database.workoutDao().insertWorkout(workout);
}
}
@@ -106,8 +91,8 @@ public class RestoreController {
private void restoreSamples(){
listener.onStatusChanged(80, context.getString(R.string.locationData));
- if(dataContainer.samples != null){
- for(WorkoutSample sample : dataContainer.samples){
+ if (dataContainer.getSamples() != null) {
+ for (WorkoutSample sample : dataContainer.getSamples()) {
database.workoutDao().insertSample(sample);
}
}
diff --git a/app/src/main/java/de/tadris/fitness/util/FileUtils.java b/app/src/main/java/de/tadris/fitness/util/FileUtils.java
new file mode 100644
index 0000000..f541e25
--- /dev/null
+++ b/app/src/main/java/de/tadris/fitness/util/FileUtils.java
@@ -0,0 +1,78 @@
+package de.tadris.fitness.util;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Environment;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import de.tadris.fitness.R;
+
+public class FileUtils {
+
+ public static void saveOrShareFile(Activity activity, Uri uri, String suffix) {
+ String[] colors = {activity.getString(R.string.share), activity.getString(R.string.save)};
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setItems(colors, (dialog, which) -> {
+ if (which == 0) {
+ shareFile(activity, uri);
+ } else {
+ try {
+ saveFile(activity, uri, suffix);
+ Toast.makeText(activity, R.string.savedToDownloads, Toast.LENGTH_LONG).show();
+ } catch (Exception e) {
+ e.printStackTrace();
+ Toast.makeText(activity, R.string.savingFailed, Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ builder.show();
+ }
+
+ private static void saveFile(Activity activity, Uri fileUri, String suffix) throws IOException {
+ File target = new File(Environment.getExternalStorageDirectory(), "Download/fitotrack" + System.currentTimeMillis() + "." + suffix);
+ if (!target.createNewFile()) {
+ throw new IOException("Cannot write to file " + target);
+ }
+ copyFile(activity, fileUri, Uri.fromFile(target));
+ }
+
+ private static void copyFile(Activity activity, Uri sourceUri, Uri targetUri) throws IOException {
+ InputStream input = activity.getContentResolver().openInputStream(sourceUri);
+ if (input == null) {
+ throw new IOException("Source file not found");
+ }
+ OutputStream output = activity.getContentResolver().openOutputStream(targetUri);
+ IOUtils.copy(input, output);
+ }
+
+ private static void shareFile(Activity activity, Uri uri) {
+ Intent intentShareFile = new Intent(Intent.ACTION_SEND);
+ intentShareFile.setDataAndType(uri, activity.getContentResolver().getType(uri));
+ intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
+ intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ activity.startActivity(Intent.createChooser(intentShareFile, activity.getString(R.string.shareFile)));
+
+ Log.d("Export", uri.toString());
+ Log.d("Export", activity.getContentResolver().getType(uri));
+ try {
+ Log.d("Export", new BufferedInputStream(activity.getContentResolver().openInputStream(uri)).toString());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9222344..dbe1905 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -35,7 +35,7 @@
Der Datenimport ist fehlgeschlagen.
Als GPX-Datei exportieren
Daten exportieren
- Erstellt ein Backup von all deinen Einstellungen und deiner Workoutdaten
+ Erstellt ein Backup von all deinern Workoutdaten
Exportieren
Fertig
GPS
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 2405657..66bc27f 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -115,7 +115,6 @@
Sistema preferido de unidades
Ajustes
Datos de exportación
- Esto toma una copia de seguridad de todas sus preferencias y datos de entrenamiento
Importar copia de seguridad
Restaurar una copia de seguridad
GPS
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1f751b4..a55932e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -136,7 +136,7 @@
Preferred system of units
Settings
Export Data
- This takes a backup of all your preferences and workout data
+ This takes a backup of all your workout data
Import Data Backup
Restore a taken backup
GPS
@@ -150,4 +150,9 @@
TextToSpeech is not available
Edit Comment
Announcement Mode
+
+ Save
+ Share
+ Saved to Downloads
+ Saving failed