diff --git a/app/build.gradle b/app/build.gradle
index 3801110..2e9cb45 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -52,23 +52,33 @@ android {
}
dependencies {
- def room_version = "2.2.0-alpha02"
-
implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+ // Android
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
- implementation "androidx.room:room-runtime:$room_version"
+ implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+
+ // Maps provider
implementation 'org.mapsforge:mapsforge-core:0.11.0'
implementation 'org.mapsforge:mapsforge-map:0.11.0'
implementation 'org.mapsforge:mapsforge-map-reader:0.11.0'
implementation 'org.mapsforge:mapsforge-themes:0.11.0'
implementation 'org.mapsforge:mapsforge-map-android:0.11.0'
implementation 'com.caverock:androidsvg:1.3'
+
implementation 'net.sf.kxml:kxml2:2.3.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
implementation 'com.github.clans:fab:1.6.4'
+
+ implementation 'stax:stax-api:1.0.1'
+ implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
+
+ // Android Room
+ def room_version = "2.2.0-alpha02"
annotationProcessor "androidx.room:room-compiler:$room_version"
- implementation 'androidx.recyclerview:recyclerview:1.0.0'
+ implementation "androidx.room:room-runtime:$room_version"
+
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}
diff --git a/app/libs/jpx-1.6.0.jar b/app/libs/jpx-1.6.0.jar
deleted file mode 100644
index d716475..0000000
Binary files a/app/libs/jpx-1.6.0.jar and /dev/null differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0fd22de..078121a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,6 +36,15 @@
+
+
+
diff --git a/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java b/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java
index 02da20c..821d8ae 100644
--- a/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java
+++ b/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java
@@ -33,7 +33,7 @@ import com.github.clans.fab.FloatingActionMenu;
import de.tadris.fitness.Instance;
import de.tadris.fitness.R;
-import de.tadris.fitness.WorkoutAdapter;
+import de.tadris.fitness.view.WorkoutAdapter;
import de.tadris.fitness.data.Workout;
public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.WorkoutAdapterListener {
diff --git a/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java b/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java
index ae31420..04cf94c 100644
--- a/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java
+++ b/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java
@@ -183,7 +183,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
new AlertDialog.Builder(this)
.setTitle(R.string.stopRecordingQuestion)
.setMessage(R.string.stopRecordingQuestionMessage)
- .setPositiveButton(R.string.okay, (dialog, which) -> stop())
+ .setPositiveButton(R.string.stop, (dialog, which) -> stop())
.setNegativeButton(R.string.continue_, null)
.create().show();
}
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 6010532..3bc8b4a 100644
--- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java
+++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java
@@ -19,12 +19,18 @@
package de.tadris.fitness.activity;
+import android.Manifest;
import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Typeface;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
+import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
@@ -33,6 +39,9 @@ import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.FileProvider;
+
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.data.Entry;
@@ -50,6 +59,9 @@ import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.layer.download.TileDownloadLayer;
import org.mapsforge.map.layer.overlay.FixedPixelCircle;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -63,9 +75,11 @@ import de.tadris.fitness.data.WorkoutManager;
import de.tadris.fitness.data.WorkoutSample;
import de.tadris.fitness.map.MapManager;
import de.tadris.fitness.map.WorkoutLayer;
+import de.tadris.fitness.util.gpx.GpxExporter;
import de.tadris.fitness.util.ThemeManager;
import de.tadris.fitness.util.unit.UnitUtils;
import de.tadris.fitness.util.WorkoutTypeCalculator;
+import de.tadris.fitness.view.ProgressDialogController;
public class ShowWorkoutActivity extends FitoTrackActivity {
static Workout selectedWorkout;
@@ -77,6 +91,7 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
MapView map;
TileDownloadLayer downloadLayer;
FixedPixelCircle highlightingCircle;
+ Handler mHandler= new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -259,7 +274,7 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
map.addLayer(workoutLayer);
final BoundingBox bounds= new BoundingBox(workoutLayer.getLatLongs()).extendMeters(50);
- new Handler().postDelayed(() -> {
+ mHandler.postDelayed(() -> {
map.getModel().mapViewPosition.setMapPosition(new MapPosition(bounds.getCenterPoint(),
(byte)(LatLongUtils.zoomForBounds(map.getDimension(), bounds, map.getModel().displayModel.getTileSize()))));
map.animate().alpha(1f).setDuration(1000).start();
@@ -318,15 +333,74 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
.create().show();
}
+ private void exportToGpx(){
+ ProgressDialogController dialogController= new ProgressDialogController(this, getString(R.string.exporting));
+ dialogController.setIndeterminate(true);
+ dialogController.show();
+ new Thread(() -> {
+ try{
+ String file= getFilesDir().getAbsolutePath() + "/shared/workout.gpx";
+ new File(file).getParentFile().mkdirs();
+ 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));
+ }catch (Exception e){
+ mHandler.post(() -> showErrorDialog(e));
+ }
+ }).start();
+ }
+
+ private void shareFile(Uri uri){
+ Intent intentShareFile = new Intent(Intent.ACTION_SEND);
+ intentShareFile.setDataAndType(uri, getContentResolver().getType(uri));
+ intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
+ intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ startActivity(Intent.createChooser(intentShareFile, getString(R.string.shareFile)));
+
+ Log.d("Export", uri.toString());
+ Log.d("Export", getContentResolver().getType(uri));
+ try {
+ Log.d("Export", new BufferedInputStream(getContentResolver().openInputStream(uri)).toString());
+ } catch (FileNotFoundException e) {
+
+ }
+ }
+
+ /*void requestPermissions(){
+ if (!hasPermission()) {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10);
+ }
+ }
+
+ public boolean hasPermission(){
+ return ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
+ }*/
+
+
+ private void showErrorDialog(Exception e){
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.error)
+ .setMessage(getString(R.string.errorGpxExportFailed) + "\n\n" + e.getMessage())
+ .setPositiveButton(R.string.okay, null)
+ .create().show();
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
- if(id == R.id.actionDeleteWorkout){
- showDeleteDialog();
- return true;
- }else if(id == android.R.id.home){
- finish();
- return true;
+ switch(id){
+ case R.id.actionDeleteWorkout:
+ showDeleteDialog();
+ return true;
+ case R.id.actionExportGpx:
+ exportToGpx();
+ return true;
+ case android.R.id.home:
+ finish();
+ return true;
}
return super.onOptionsItemSelected(item);
}
diff --git a/app/src/main/java/de/tadris/fitness/data/Workout.java b/app/src/main/java/de/tadris/fitness/data/Workout.java
index 6340695..90141b2 100644
--- a/app/src/main/java/de/tadris/fitness/data/Workout.java
+++ b/app/src/main/java/de/tadris/fitness/data/Workout.java
@@ -22,6 +22,9 @@ package de.tadris.fitness.data;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
@Entity(tableName = "workout")
public class Workout{
@@ -65,5 +68,13 @@ public class Workout{
public int calorie;
+ public String toString(){
+ if(comment.length() > 2){
+ return comment;
+ }else{
+ return SimpleDateFormat.getDateTimeInstance().format(new Date(start));
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/de/tadris/fitness/util/GpxExporter.java b/app/src/main/java/de/tadris/fitness/util/GpxExporter.java
deleted file mode 100644
index 272f0b7..0000000
--- a/app/src/main/java/de/tadris/fitness/util/GpxExporter.java
+++ /dev/null
@@ -1,56 +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.util;
-
-import android.content.Context;
-
-import de.tadris.fitness.Instance;
-import de.tadris.fitness.data.Workout;
-import de.tadris.fitness.data.WorkoutSample;
-import io.jenetics.jpx.GPX;
-import io.jenetics.jpx.Track;
-import io.jenetics.jpx.TrackSegment;
-
-public class GpxExporter {
-
- public static void exportWorkout(Context context, Workout workout){
- GPX.Builder builder= GPX.builder();
-
- builder.addTrack(toTrack(context, workout));
-
- }
-
- public static Track toTrack(Context context, Workout workout){
- Track.Builder track= Track.builder();
- TrackSegment.Builder segment= TrackSegment.builder();
-
- WorkoutSample[] samples= Instance.getInstance(context).db.workoutDao().getAllSamplesOfWorkout(workout.id);
- for(WorkoutSample sample : samples){
- segment.addPoint(p -> p.lat(sample.lat).lon(sample.lon).ele(sample.elevation).speed(sample.speed).time(sample.absoluteTime));
- }
-
- track.addSegment(segment.build());
- track.src("FitoTrack");
- track.type(workout.workoutType);
-
- return track.build();
- }
-
-}
diff --git a/app/src/main/java/de/tadris/fitness/util/gpx/Gpx.java b/app/src/main/java/de/tadris/fitness/util/gpx/Gpx.java
new file mode 100644
index 0000000..fb92f46
--- /dev/null
+++ b/app/src/main/java/de/tadris/fitness/util/gpx/Gpx.java
@@ -0,0 +1,60 @@
+package de.tadris.fitness.util.gpx;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import java.util.List;
+
+@JacksonXmlRootElement(localName = "gpx")
+public class Gpx {
+
+ @JacksonXmlProperty(isAttribute = true)
+ String version;
+
+ @JacksonXmlProperty(isAttribute = true)
+ String creator;
+
+ Metadata metadata;
+
+ String name;
+ String desc;
+
+ @JacksonXmlElementWrapper(useWrapping = false)
+ List