mirror of
https://github.com/russok/FitoTrack.git
synced 2025-10-29 00:32:11 -07:00
Merge branch 'develop' into feature-unit_systems
# Conflicts: # app/src/main/res/values/strings.xml
This commit is contained in:
commit
4ecf319fd4
@ -52,23 +52,33 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
def room_version = "2.2.0-alpha02"
|
|
||||||
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
// Android
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
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-core:0.11.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map:0.11.0'
|
implementation 'org.mapsforge:mapsforge-map:0.11.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-reader:0.11.0'
|
implementation 'org.mapsforge:mapsforge-map-reader:0.11.0'
|
||||||
implementation 'org.mapsforge:mapsforge-themes:0.11.0'
|
implementation 'org.mapsforge:mapsforge-themes:0.11.0'
|
||||||
implementation 'org.mapsforge:mapsforge-map-android:0.11.0'
|
implementation 'org.mapsforge:mapsforge-map-android:0.11.0'
|
||||||
implementation 'com.caverock:androidsvg:1.3'
|
implementation 'com.caverock:androidsvg:1.3'
|
||||||
|
|
||||||
implementation 'net.sf.kxml:kxml2:2.3.0'
|
implementation 'net.sf.kxml:kxml2:2.3.0'
|
||||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
||||||
implementation 'com.github.clans:fab:1.6.4'
|
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"
|
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'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -36,6 +36,15 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="de.tadris.fitness.fileprovider"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
android:exported="false">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/filepaths" />
|
||||||
|
</provider>
|
||||||
<service android:name=".location.LocationListener"></service>
|
<service android:name=".location.LocationListener"></service>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import com.github.clans.fab.FloatingActionMenu;
|
|||||||
|
|
||||||
import de.tadris.fitness.Instance;
|
import de.tadris.fitness.Instance;
|
||||||
import de.tadris.fitness.R;
|
import de.tadris.fitness.R;
|
||||||
import de.tadris.fitness.WorkoutAdapter;
|
import de.tadris.fitness.view.WorkoutAdapter;
|
||||||
import de.tadris.fitness.data.Workout;
|
import de.tadris.fitness.data.Workout;
|
||||||
|
|
||||||
public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.WorkoutAdapterListener {
|
public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.WorkoutAdapterListener {
|
||||||
|
|||||||
@ -183,7 +183,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
|||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setTitle(R.string.stopRecordingQuestion)
|
.setTitle(R.string.stopRecordingQuestion)
|
||||||
.setMessage(R.string.stopRecordingQuestionMessage)
|
.setMessage(R.string.stopRecordingQuestionMessage)
|
||||||
.setPositiveButton(R.string.okay, (dialog, which) -> stop())
|
.setPositiveButton(R.string.stop, (dialog, which) -> stop())
|
||||||
.setNegativeButton(R.string.continue_, null)
|
.setNegativeButton(R.string.continue_, null)
|
||||||
.create().show();
|
.create().show();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,18 @@
|
|||||||
|
|
||||||
package de.tadris.fitness.activity;
|
package de.tadris.fitness.activity;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -33,6 +39,9 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.TextView;
|
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.charts.LineChart;
|
||||||
import com.github.mikephil.charting.components.Description;
|
import com.github.mikephil.charting.components.Description;
|
||||||
import com.github.mikephil.charting.data.Entry;
|
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.download.TileDownloadLayer;
|
||||||
import org.mapsforge.map.layer.overlay.FixedPixelCircle;
|
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.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -63,9 +75,11 @@ import de.tadris.fitness.data.WorkoutManager;
|
|||||||
import de.tadris.fitness.data.WorkoutSample;
|
import de.tadris.fitness.data.WorkoutSample;
|
||||||
import de.tadris.fitness.map.MapManager;
|
import de.tadris.fitness.map.MapManager;
|
||||||
import de.tadris.fitness.map.WorkoutLayer;
|
import de.tadris.fitness.map.WorkoutLayer;
|
||||||
|
import de.tadris.fitness.util.gpx.GpxExporter;
|
||||||
import de.tadris.fitness.util.ThemeManager;
|
import de.tadris.fitness.util.ThemeManager;
|
||||||
import de.tadris.fitness.util.unit.UnitUtils;
|
import de.tadris.fitness.util.unit.UnitUtils;
|
||||||
import de.tadris.fitness.util.WorkoutTypeCalculator;
|
import de.tadris.fitness.util.WorkoutTypeCalculator;
|
||||||
|
import de.tadris.fitness.view.ProgressDialogController;
|
||||||
|
|
||||||
public class ShowWorkoutActivity extends FitoTrackActivity {
|
public class ShowWorkoutActivity extends FitoTrackActivity {
|
||||||
static Workout selectedWorkout;
|
static Workout selectedWorkout;
|
||||||
@ -77,6 +91,7 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
|||||||
MapView map;
|
MapView map;
|
||||||
TileDownloadLayer downloadLayer;
|
TileDownloadLayer downloadLayer;
|
||||||
FixedPixelCircle highlightingCircle;
|
FixedPixelCircle highlightingCircle;
|
||||||
|
Handler mHandler= new Handler();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -259,7 +274,7 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
|||||||
map.addLayer(workoutLayer);
|
map.addLayer(workoutLayer);
|
||||||
|
|
||||||
final BoundingBox bounds= new BoundingBox(workoutLayer.getLatLongs()).extendMeters(50);
|
final BoundingBox bounds= new BoundingBox(workoutLayer.getLatLongs()).extendMeters(50);
|
||||||
new Handler().postDelayed(() -> {
|
mHandler.postDelayed(() -> {
|
||||||
map.getModel().mapViewPosition.setMapPosition(new MapPosition(bounds.getCenterPoint(),
|
map.getModel().mapViewPosition.setMapPosition(new MapPosition(bounds.getCenterPoint(),
|
||||||
(byte)(LatLongUtils.zoomForBounds(map.getDimension(), bounds, map.getModel().displayModel.getTileSize()))));
|
(byte)(LatLongUtils.zoomForBounds(map.getDimension(), bounds, map.getModel().displayModel.getTileSize()))));
|
||||||
map.animate().alpha(1f).setDuration(1000).start();
|
map.animate().alpha(1f).setDuration(1000).start();
|
||||||
@ -318,13 +333,72 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
|||||||
.create().show();
|
.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
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if(id == R.id.actionDeleteWorkout){
|
switch(id){
|
||||||
|
case R.id.actionDeleteWorkout:
|
||||||
showDeleteDialog();
|
showDeleteDialog();
|
||||||
return true;
|
return true;
|
||||||
}else if(id == android.R.id.home){
|
case R.id.actionExportGpx:
|
||||||
|
exportToGpx();
|
||||||
|
return true;
|
||||||
|
case android.R.id.home:
|
||||||
finish();
|
finish();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,9 @@ package de.tadris.fitness.data;
|
|||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@Entity(tableName = "workout")
|
@Entity(tableName = "workout")
|
||||||
public class Workout{
|
public class Workout{
|
||||||
|
|
||||||
@ -65,5 +68,13 @@ public class Workout{
|
|||||||
|
|
||||||
public int calorie;
|
public int calorie;
|
||||||
|
|
||||||
|
public String toString(){
|
||||||
|
if(comment.length() > 2){
|
||||||
|
return comment;
|
||||||
|
}else{
|
||||||
|
return SimpleDateFormat.getDateTimeInstance().format(new Date(start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019 Jannis Scheibe <jannis@tadris.de>
|
|
||||||
*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
60
app/src/main/java/de/tadris/fitness/util/gpx/Gpx.java
Normal file
60
app/src/main/java/de/tadris/fitness/util/gpx/Gpx.java
Normal file
@ -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<Track> trk;
|
||||||
|
|
||||||
|
public Gpx(){}
|
||||||
|
|
||||||
|
public Gpx(String version, String creator, Metadata metadata, String name, String desc, List<Track> trk) {
|
||||||
|
this.version = version;
|
||||||
|
this.creator = creator;
|
||||||
|
this.metadata = metadata;
|
||||||
|
this.name = name;
|
||||||
|
this.desc = desc;
|
||||||
|
this.trk = trk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCreator() {
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Metadata getMetadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Track> getTrk() {
|
||||||
|
return trk;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Jannis Scheibe <jannis@tadris.de>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import de.tadris.fitness.Instance;
|
||||||
|
import de.tadris.fitness.data.Workout;
|
||||||
|
import de.tadris.fitness.data.WorkoutSample;
|
||||||
|
|
||||||
|
public class GpxExporter {
|
||||||
|
|
||||||
|
public static void exportWorkout(Context context, Workout workout, File file) throws IOException {
|
||||||
|
XmlMapper mapper= new XmlMapper();
|
||||||
|
mapper.writeValue(file, getGpxFromWorkout(context, workout));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Gpx getGpxFromWorkout(Context context, Workout workout){
|
||||||
|
Gpx gpx= new Gpx();
|
||||||
|
gpx.name= workout.toString();
|
||||||
|
gpx.version= "1.1";
|
||||||
|
gpx.creator= "FitoTrack";
|
||||||
|
gpx.metadata= new Metadata(workout.toString(), workout.comment, getDateTime(workout.start));
|
||||||
|
gpx.trk= new ArrayList<>();
|
||||||
|
gpx.trk.add(getTrackFromWorkout(context, workout, 0));
|
||||||
|
|
||||||
|
return gpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Track getTrackFromWorkout(Context context, Workout workout, int number){
|
||||||
|
WorkoutSample[] samples= Instance.getInstance(context).db.workoutDao().getAllSamplesOfWorkout(workout.id);
|
||||||
|
Track track= new Track();
|
||||||
|
track.number= number;
|
||||||
|
track.name= workout.toString();
|
||||||
|
track.cmt= workout.comment;
|
||||||
|
track.desc= workout.comment;
|
||||||
|
track.src= "FitoTrack";
|
||||||
|
track.type= workout.workoutType;
|
||||||
|
track.trkseg= new ArrayList<>();
|
||||||
|
|
||||||
|
TrackSegment segment= new TrackSegment();
|
||||||
|
segment.trkpt= new ArrayList<>();
|
||||||
|
|
||||||
|
for(WorkoutSample sample : samples){
|
||||||
|
segment.trkpt.add(new TrackPoint(sample.lat, sample.lon, sample.elevation,
|
||||||
|
getDateTime(sample.absoluteTime), "gps",
|
||||||
|
new TrackPointExtension(sample.speed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
track.trkseg.add(segment);
|
||||||
|
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||||
|
|
||||||
|
public static String getDateTime(long time){
|
||||||
|
return getDateTime(new Date(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDateTime(Date date){
|
||||||
|
return formatter.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
41
app/src/main/java/de/tadris/fitness/util/gpx/Metadata.java
Normal file
41
app/src/main/java/de/tadris/fitness/util/gpx/Metadata.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
public class Metadata {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String desc;
|
||||||
|
String time;
|
||||||
|
|
||||||
|
public Metadata() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Metadata(String name, String desc, String time) {
|
||||||
|
this.name = name;
|
||||||
|
this.desc = desc;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDesc(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
app/src/main/java/de/tadris/fitness/util/gpx/Track.java
Normal file
86
app/src/main/java/de/tadris/fitness/util/gpx/Track.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Track {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String cmt;
|
||||||
|
String desc;
|
||||||
|
String src;
|
||||||
|
int number;
|
||||||
|
String type;
|
||||||
|
|
||||||
|
@JacksonXmlElementWrapper(useWrapping = false)
|
||||||
|
List<TrackSegment> trkseg;
|
||||||
|
|
||||||
|
public Track(){}
|
||||||
|
|
||||||
|
public Track(String name, String cmt, String desc, String src, int number, String type, List<TrackSegment> trkseg) {
|
||||||
|
this.name = name;
|
||||||
|
this.cmt = cmt;
|
||||||
|
this.desc = desc;
|
||||||
|
this.src = src;
|
||||||
|
this.number = number;
|
||||||
|
this.type = type;
|
||||||
|
this.trkseg = trkseg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCmt() {
|
||||||
|
return cmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCmt(String cmt) {
|
||||||
|
this.cmt = cmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDesc(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSrc() {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSrc(String src) {
|
||||||
|
this.src = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(int number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TrackSegment> getTrkseg() {
|
||||||
|
return trkseg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrkseg(List<TrackSegment> trkseg) {
|
||||||
|
this.trkseg = trkseg;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
app/src/main/java/de/tadris/fitness/util/gpx/TrackPoint.java
Normal file
79
app/src/main/java/de/tadris/fitness/util/gpx/TrackPoint.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||||
|
|
||||||
|
public class TrackPoint {
|
||||||
|
|
||||||
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
|
double lat;
|
||||||
|
|
||||||
|
@JacksonXmlProperty(isAttribute = true)
|
||||||
|
double lon;
|
||||||
|
|
||||||
|
double ele;
|
||||||
|
|
||||||
|
String time;
|
||||||
|
|
||||||
|
String fix;
|
||||||
|
|
||||||
|
TrackPointExtension extensions;
|
||||||
|
|
||||||
|
public TrackPoint(){}
|
||||||
|
|
||||||
|
public TrackPoint(double lat, double lon, double ele, String time, String fix, TrackPointExtension extensions) {
|
||||||
|
this.lat = lat;
|
||||||
|
this.lon = lon;
|
||||||
|
this.ele = ele;
|
||||||
|
this.time = time;
|
||||||
|
this.fix = fix;
|
||||||
|
this.extensions = extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLat() {
|
||||||
|
return lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLat(double lat) {
|
||||||
|
this.lat = lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLon() {
|
||||||
|
return lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLon(double lon) {
|
||||||
|
this.lon = lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getEle() {
|
||||||
|
return ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEle(double ele) {
|
||||||
|
this.ele = ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFix() {
|
||||||
|
return fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFix(String fix) {
|
||||||
|
this.fix = fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TrackPointExtension getExtensions() {
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExtensions(TrackPointExtension extensions) {
|
||||||
|
this.extensions = extensions;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
public class TrackPointExtension {
|
||||||
|
|
||||||
|
double speed;
|
||||||
|
|
||||||
|
public TrackPointExtension(){}
|
||||||
|
|
||||||
|
public TrackPointExtension(double speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(double speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package de.tadris.fitness.util.gpx;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TrackSegment {
|
||||||
|
|
||||||
|
@JacksonXmlElementWrapper(useWrapping = false)
|
||||||
|
List<TrackPoint> trkpt;
|
||||||
|
|
||||||
|
public TrackSegment(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TrackSegment(List<TrackPoint> trkpt) {
|
||||||
|
this.trkpt = trkpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TrackPoint> getTrkpt() {
|
||||||
|
return trkpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrkpt(List<TrackPoint> trkpt) {
|
||||||
|
this.trkpt = trkpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package de.tadris.fitness.view;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import de.tadris.fitness.R;
|
||||||
|
|
||||||
|
public class ProgressDialogController {
|
||||||
|
|
||||||
|
private Activity context;
|
||||||
|
private Dialog dialog;
|
||||||
|
private TextView infoView;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
|
public ProgressDialogController(Activity context, String title) {
|
||||||
|
this(context);
|
||||||
|
setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgressDialogController(Activity context) {
|
||||||
|
this.context = context;
|
||||||
|
this.dialog= new Dialog(context);
|
||||||
|
initDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDialog(){
|
||||||
|
dialog.setContentView(R.layout.dialog_progress);
|
||||||
|
infoView= dialog.findViewById(R.id.dialogProgressInfo);
|
||||||
|
progressBar= dialog.findViewById(R.id.dialogProgressBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title){
|
||||||
|
dialog.setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndeterminate(boolean indeterminate){
|
||||||
|
progressBar.setIndeterminate(indeterminate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(int progress){
|
||||||
|
progressBar.setProgress(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(int progress, String info){
|
||||||
|
setProgress(progress);
|
||||||
|
infoView.setText(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(){
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(){
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.tadris.fitness;
|
package de.tadris.fitness.view;
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -30,6 +30,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import de.tadris.fitness.R;
|
||||||
import de.tadris.fitness.data.Workout;
|
import de.tadris.fitness.data.Workout;
|
||||||
import de.tadris.fitness.util.unit.UnitUtils;
|
import de.tadris.fitness.util.unit.UnitUtils;
|
||||||
import de.tadris.fitness.util.WorkoutTypeCalculator;
|
import de.tadris.fitness.util.WorkoutTypeCalculator;
|
||||||
18
app/src/main/res/layout/dialog_progress.xml
Normal file
18
app/src/main/res/layout/dialog_progress.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/dialogProgressBar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/dialogProgressInfo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
@ -23,5 +23,5 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/actionRecordingStop"
|
android:id="@+id/actionRecordingStop"
|
||||||
android:showAsAction="ifRoom"
|
android:showAsAction="ifRoom"
|
||||||
android:title="@string/workoutStopRecording" />
|
android:title="@string/stop" />
|
||||||
</menu>
|
</menu>
|
||||||
@ -20,8 +20,10 @@
|
|||||||
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/actionExportGpx"
|
||||||
|
android:title="@string/exportAsGpxFile" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/actionDeleteWorkout"
|
android:id="@+id/actionDeleteWorkout"
|
||||||
android:showAsAction="ifRoom"
|
|
||||||
android:title="@string/delete" />
|
android:title="@string/delete" />
|
||||||
</menu>
|
</menu>
|
||||||
@ -20,8 +20,13 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">FitoTrack</string>
|
<string name="app_name">FitoTrack</string>
|
||||||
<string name="workout_add">Add</string>
|
<string name="workout_add">Add</string>
|
||||||
<string name="workoutStopRecording">Stop</string>
|
<string name="stop">Stop</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
|
<string name="exporting">Exporting</string>
|
||||||
|
|
||||||
|
<string name="error">Error</string>
|
||||||
|
<string name="errorGpxExportFailed">The GPX export has been failed.</string>
|
||||||
|
<string name="shareFile">Share file</string>
|
||||||
|
|
||||||
<string name="pref_ringtone_silent">Silent</string>
|
<string name="pref_ringtone_silent">Silent</string>
|
||||||
|
|
||||||
@ -70,6 +75,7 @@
|
|||||||
<string name="trackingInfoDescription">Info about the tracker running</string>
|
<string name="trackingInfoDescription">Info about the tracker running</string>
|
||||||
|
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
|
<string name="exportAsGpxFile">Export as GPX-File</string>
|
||||||
<string name="pref_weight">Your Weight</string>
|
<string name="pref_weight">Your Weight</string>
|
||||||
<string name="pref_weight_summary">Your weight is needed to calculate the burned calories</string>
|
<string name="pref_weight_summary">Your weight is needed to calculate the burned calories</string>
|
||||||
<string name="pref_unit_system">Preferred system of units</string>
|
<string name="pref_unit_system">Preferred system of units</string>
|
||||||
|
|||||||
4
app/src/main/res/xml/filepaths.xml
Normal file
4
app/src/main/res/xml/filepaths.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths>
|
||||||
|
<files-path path="shared/" name="share" />
|
||||||
|
</paths>
|
||||||
Loading…
x
Reference in New Issue
Block a user