Merge branch 'feature-height-data' into develop

This commit is contained in:
jannis 2019-08-25 13:17:31 +02:00
commit fb194d1031
15 changed files with 363 additions and 120 deletions

View File

@ -1,4 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="de.tadris.fitness"> package="de.tadris.fitness">
@ -46,7 +65,8 @@
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" /> android:resource="@xml/filepaths" />
</provider> </provider>
<service android:name=".location.LocationListener"></service> <service android:name=".recording.LocationListener" />
<service android:name=".recording.PressureService" />
</application> </application>
</manifest> </manifest>

View File

@ -21,14 +21,17 @@ package de.tadris.fitness;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull;
import androidx.room.Room; import androidx.room.Room;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.tadris.fitness.data.AppDatabase; import de.tadris.fitness.data.AppDatabase;
import de.tadris.fitness.data.UserPreferences; import de.tadris.fitness.data.UserPreferences;
import de.tadris.fitness.location.LocationListener; import de.tadris.fitness.recording.LocationListener;
import de.tadris.fitness.util.unit.UnitUtils; import de.tadris.fitness.util.unit.UnitUtils;
public class Instance { public class Instance {
@ -48,9 +51,45 @@ public class Instance {
public List<LocationListener.LocationChangeListener> locationChangeListeners= new ArrayList<>(); public List<LocationListener.LocationChangeListener> locationChangeListeners= new ArrayList<>();
public UserPreferences userPreferences; public UserPreferences userPreferences;
public boolean pressureAvailable= false;
public float lastPressure= 0;
private Instance(Context context) { private Instance(Context context) {
userPreferences= new UserPreferences(context); userPreferences= new UserPreferences(context);
db = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME) db = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
.addMigrations(new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
try{
database.beginTransaction();
database.execSQL("ALTER table workout add descent REAL NOT NULL DEFAULT 0;");
database.execSQL("ALTER table workout add ascent REAL NOT NULL DEFAULT 0");
database.execSQL("ALTER TABLE workout_sample RENAME TO workout_sample2;");
database.execSQL("CREATE TABLE workout_sample (" +
"id INTEGER NOT NULL DEFAULT NULL PRIMARY KEY," +
"relativeTime INTEGER NOT NULL DEFAULT NULL," +
"elevation REAL NOT NULL DEFAULT NULL," +
"absoluteTime INTEGER NOT NULL DEFAULT NULL," +
"lat REAL NOT NULL DEFAULT NULL," +
"lon REAL NOT NULL DEFAULT NULL," +
"speed REAL NOT NULL DEFAULT NULL," +
"workout_id INTEGER NOT NULL DEFAULT NULL," +
"FOREIGN KEY (workout_id) REFERENCES workout(id) ON DELETE CASCADE);");
database.execSQL("INSERT INTO workout_sample (id, relativeTime, elevation, absoluteTime, lat, lon, speed, workout_id) " +
"SELECT id, relativeTime, elevation, absoluteTime, lat, lon, speed, workout_id FROM workout_sample2");
database.execSQL("DROP TABLE workout_sample2");
database.setTransactionSuccessful();
}finally {
database.endTransaction();
}
}
})
.allowMainThreadQueries() .allowMainThreadQueries()
.build(); .build();
UnitUtils.setUnit(context); UnitUtils.setUnit(context);

View File

@ -53,10 +53,11 @@ import java.util.List;
import de.tadris.fitness.Instance; import de.tadris.fitness.Instance;
import de.tadris.fitness.R; import de.tadris.fitness.R;
import de.tadris.fitness.data.Workout; import de.tadris.fitness.data.Workout;
import de.tadris.fitness.location.LocationListener;
import de.tadris.fitness.location.WorkoutRecorder;
import de.tadris.fitness.map.MapManager; import de.tadris.fitness.map.MapManager;
import de.tadris.fitness.map.tilesource.TileSources; import de.tadris.fitness.map.tilesource.TileSources;
import de.tadris.fitness.recording.LocationListener;
import de.tadris.fitness.recording.PressureService;
import de.tadris.fitness.recording.WorkoutRecorder;
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;
@ -75,6 +76,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
private Handler mHandler= new Handler(); private Handler mHandler= new Handler();
PowerManager.WakeLock wakeLock; PowerManager.WakeLock wakeLock;
Intent locationListener; Intent locationListener;
Intent pressureService;
private boolean saved= false; private boolean saved= false;
@Override @Override
@ -157,7 +159,10 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
}).start(); }).start();
} }
int i= 0;
private void updateDescription(){ private void updateDescription(){
i++;
timeView.setText(UnitUtils.getHourMinuteSecondTime(recorder.getDuration())); timeView.setText(UnitUtils.getHourMinuteSecondTime(recorder.getDuration()));
infoViews[0].setText(getString(R.string.workoutDistance), UnitUtils.getDistance(recorder.getDistance())); infoViews[0].setText(getString(R.string.workoutDistance), UnitUtils.getDistance(recorder.getDistance()));
infoViews[1].setText(getString(R.string.workoutBurnedEnergy), recorder.getCalories() + " kcal"); infoViews[1].setText(getString(R.string.workoutBurnedEnergy), recorder.getCalories() + " kcal");
@ -231,18 +236,22 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
public void stopListener(){ public void stopListener(){
stopService(locationListener); stopService(locationListener);
stopService(pressureService);
} }
public void startListener(){ public void startListener(){
if(locationListener == null){ if(locationListener == null){
locationListener= new Intent(this, LocationListener.class); locationListener= new Intent(this, LocationListener.class);
pressureService= new Intent(this, PressureService.class);
}else{ }else{
stopListener(); stopListener();
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(locationListener); startForegroundService(locationListener);
startService(pressureService);
}else{ }else{
startService(locationListener); startService(locationListener);
startService(pressureService);
} }
checkGpsStatus(); checkGpsStatus();
} }

View File

@ -131,6 +131,13 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
addKeyValue(getString(R.string.workoutTotalEnergy), workout.calorie + " kcal", addKeyValue(getString(R.string.workoutTotalEnergy), workout.calorie + " kcal",
getString(R.string.workoutEnergyConsumption), UnitUtils.getRelativeEnergyConsumption((double)workout.calorie / ((double)workout.length / 1000))); getString(R.string.workoutEnergyConsumption), UnitUtils.getRelativeEnergyConsumption((double)workout.calorie / ((double)workout.length / 1000)));
addTitle(getString(R.string.height));
addKeyValue(getString(R.string.workoutAscent), UnitUtils.getDistance((int)workout.ascent),
getString(R.string.workoutDescent), UnitUtils.getDistance((int)workout.descent));
addHeightDiagram();
} }
@ -199,20 +206,20 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
root.addView(v); root.addView(v);
} }
void addSpeedDiagram(){ void addDiagram(SampleConverter converter){
LineChart chart= new LineChart(this); LineChart chart= new LineChart(this);
WorkoutManager.roundSpeedValues(samples); converter.onCreate();
List<Entry> entries = new ArrayList<>(); List<Entry> entries = new ArrayList<>();
for (WorkoutSample sample : samples) { for (WorkoutSample sample : samples) {
// turn your data into Entry objects // turn your data into Entry objects
Entry e= new Entry((float)(sample.relativeTime) / 1000f / 60f, (float)sample.tmpRoundedSpeed*3.6f); Entry e= new Entry((float)(sample.relativeTime) / 1000f / 60f, converter.getValue(sample));
entries.add(e); entries.add(e);
sample.tmpEntry= e; converter.sampleGetsEntry(sample, e);
} }
LineDataSet dataSet = new LineDataSet(entries, "Speed"); // add entries to dataset // TODO: localisatoin LineDataSet dataSet = new LineDataSet(entries, converter.getName()); // add entries to dataset
dataSet.setColor(getThemePrimaryColor()); dataSet.setColor(getThemePrimaryColor());
dataSet.setValueTextColor(getThemePrimaryColor()); dataSet.setValueTextColor(getThemePrimaryColor());
dataSet.setDrawCircles(false); dataSet.setDrawCircles(false);
@ -220,11 +227,12 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
Description description= new Description(); Description description= new Description();
description.setText("min - km/h"); description.setText(converter.getDescription());
LineData lineData = new LineData(dataSet); LineData lineData = new LineData(dataSet);
chart.setData(lineData); chart.setData(lineData);
chart.setScaleEnabled(false); chart.setScaleXEnabled(true);
chart.setScaleYEnabled(false);
chart.setDescription(description); chart.setDescription(description);
chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override @Override
@ -232,7 +240,7 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
onNothingSelected(); onNothingSelected();
Paint p= AndroidGraphicFactory.INSTANCE.createPaint(); Paint p= AndroidGraphicFactory.INSTANCE.createPaint();
p.setColor(Color.BLUE); p.setColor(Color.BLUE);
highlightingCircle= new FixedPixelCircle(getSamplebyTime(e).toLatLong(), 10, p, null); highlightingCircle= new FixedPixelCircle(findSample(converter, e).toLatLong(), 10, p, null);
map.addLayer(highlightingCircle); map.addLayer(highlightingCircle);
} }
@ -248,9 +256,84 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
root.addView(chart, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getWindowManager().getDefaultDisplay().getWidth()*3/4)); root.addView(chart, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getWindowManager().getDefaultDisplay().getWidth()*3/4));
} }
WorkoutSample getSamplebyTime(Entry entry){ interface SampleConverter{
void onCreate();
float getValue(WorkoutSample sample);
void sampleGetsEntry(WorkoutSample sample, Entry entry);
String getName();
String getDescription();
boolean compare(WorkoutSample sample, Entry entry);
}
void addHeightDiagram(){
addDiagram(new SampleConverter() {
@Override
public void onCreate() { }
@Override
public float getValue(WorkoutSample sample) {
return (float)UnitUtils.CHOSEN_SYSTEM.getDistanceFromMeters(sample.elevation);
}
@Override
public void sampleGetsEntry(WorkoutSample sample, Entry entry) {
sample.tmpHeightEntry= entry;
}
@Override
public String getName() {
return getString(R.string.height);
}
@Override
public String getDescription() {
return "min - " + UnitUtils.CHOSEN_SYSTEM.getShortDistanceUnit();
}
@Override
public boolean compare(WorkoutSample sample, Entry entry) {
return sample.tmpHeightEntry.equalTo(entry);
}
});
}
void addSpeedDiagram(){
addDiagram(new SampleConverter() {
@Override
public void onCreate() {
WorkoutManager.roundSpeedValues(samples);
}
@Override
public float getValue(WorkoutSample sample) {
return (float)UnitUtils.CHOSEN_SYSTEM.getSpeedFromMeterPerSecond(sample.tmpRoundedSpeed);
}
@Override
public void sampleGetsEntry(WorkoutSample sample, Entry entry) {
sample.tmpSpeedEntry= entry;
}
@Override
public String getName() {
return getString(R.string.workoutSpeed);
}
@Override
public String getDescription() {
return "min - " + UnitUtils.CHOSEN_SYSTEM.getSpeedUnit();
}
@Override
public boolean compare(WorkoutSample sample, Entry entry) {
return sample.tmpSpeedEntry.equalTo(entry);
}
});
}
WorkoutSample findSample(SampleConverter converter, Entry entry){
for(WorkoutSample sample : samples){ for(WorkoutSample sample : samples){
if(sample.tmpEntry.equalTo(entry)){ if(converter.compare(sample, entry)){
return sample; return sample;
} }
} }

View File

@ -22,7 +22,7 @@ package de.tadris.fitness.data;
import androidx.room.Database; import androidx.room.Database;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
@Database(version = 1, entities = {Workout.class, WorkoutSample.class}) @Database(version = 2, entities = {Workout.class, WorkoutSample.class})
public abstract class AppDatabase extends RoomDatabase { public abstract class AppDatabase extends RoomDatabase {
public abstract WorkoutDao workoutDao(); public abstract WorkoutDao workoutDao();
} }

View File

@ -22,10 +22,13 @@ package de.tadris.fitness.data;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
@Entity(tableName = "workout") @Entity(tableName = "workout")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Workout{ public class Workout{
public static final String WORKOUT_TYPE_RUNNING= "running"; public static final String WORKOUT_TYPE_RUNNING= "running";
@ -66,6 +69,11 @@ public class Workout{
public String workoutType; public String workoutType;
public float ascent;
public float descent;
public int calorie; public int calorie;
public String toString(){ public String toString(){

View File

@ -20,6 +20,7 @@
package de.tadris.fitness.data; package de.tadris.fitness.data;
import android.content.Context; import android.content.Context;
import android.hardware.SensorManager;
import android.util.Log; import android.util.Log;
import java.util.List; import java.util.List;
@ -61,10 +62,14 @@ public class WorkoutManager {
// Setting workoutId in the samples // Setting workoutId in the samples
int i= 0; int i= 0;
double topSpeed= 0; double topSpeed= 0;
double elevationSum= 0; // Sum of elevation
double pressureSum= 0; // Sum of elevation
for(WorkoutSample sample : samples){ for(WorkoutSample sample : samples){
i++; i++;
sample.id= workout.id + i; sample.id= workout.id + i;
sample.workoutId= workout.id; sample.workoutId= workout.id;
elevationSum+= sample.elevation;
pressureSum+= sample.tmpPressure;
if(sample.speed > topSpeed){ if(sample.speed > topSpeed){
topSpeed= sample.speed; topSpeed= sample.speed;
} }
@ -72,6 +77,36 @@ public class WorkoutManager {
workout.topSpeed= topSpeed; workout.topSpeed= topSpeed;
// Calculating height data
boolean pressureDataAvailable= samples.get(0).tmpPressure != -1;
double avgElevation= elevationSum / samples.size();
double avgPressure= pressureSum / samples.size();
workout.ascent = 0;
workout.descent = 0;
for(i= 0; i < samples.size(); i++){
WorkoutSample sample= samples.get(i);
if(pressureDataAvailable){
// Altitude Difference to Average Elevation in meters
float altitude_difference =
SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, sample.tmpPressure) -
SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, (float) avgPressure);
sample.elevation= avgElevation + altitude_difference;
} // Else: use already set GPS elevation in WorkoutSample.elevation
if(i >= 1){
WorkoutSample lastSample= samples.get(i-1);
double diff= sample.elevation - lastSample.elevation;
if(diff > 0){
workout.ascent += diff;
}else{
workout.descent += Math.abs(diff);
}
}
}
// Saving workout and samples // Saving workout and samples
db.workoutDao().insertWorkoutAndSamples(workout, samples.toArray(new WorkoutSample[0])); db.workoutDao().insertWorkoutAndSamples(workout, samples.toArray(new WorkoutSample[0]));
@ -91,4 +126,15 @@ public class WorkoutManager {
} }
} }
public static void calculateInclination(List<WorkoutSample> samples){
samples.get(0).tmpInclination= 0;
for(int i= 1; i < samples.size(); i++){
WorkoutSample sample= samples.get(i);
WorkoutSample lastSample= samples.get(i);
double elevationDifference= sample.elevation - sample.elevation;
double distance= sample.toLatLong().sphericalDistance(lastSample.toLatLong());
sample.tmpInclination= (float)(elevationDifference*100/distance);
}
}
} }

View File

@ -26,6 +26,7 @@ import androidx.room.Ignore;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.data.Entry;
import org.mapsforge.core.model.LatLong; import org.mapsforge.core.model.LatLong;
@ -38,6 +39,7 @@ import static androidx.room.ForeignKey.CASCADE;
parentColumns = "id", parentColumns = "id",
childColumns = "workout_id", childColumns = "workout_id",
onDelete = CASCADE)) onDelete = CASCADE))
@JsonIgnoreProperties(ignoreUnknown = true)
public class WorkoutSample{ public class WorkoutSample{
@PrimaryKey @PrimaryKey
@ -56,18 +58,28 @@ public class WorkoutSample{
public double elevation; public double elevation;
public double relativeElevation;
public double speed; public double speed;
@JsonIgnore @JsonIgnore
@Ignore @Ignore
public Entry tmpEntry; public Entry tmpHeightEntry;
@JsonIgnore
@Ignore
public Entry tmpSpeedEntry;
@JsonIgnore @JsonIgnore
@Ignore @Ignore
public double tmpRoundedSpeed; public double tmpRoundedSpeed;
@JsonIgnore
@Ignore
public float tmpPressure;
@JsonIgnore
@Ignore
public float tmpInclination;
public LatLong toLatLong(){ public LatLong toLatLong(){
return new LatLong(lat, lon); return new LatLong(lat, lon);
} }

View File

@ -1,98 +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.location;
import android.graphics.drawable.Drawable;
import org.mapsforge.core.graphics.Canvas;
import org.mapsforge.core.graphics.Paint;
import org.mapsforge.core.graphics.Style;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.Point;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.layer.Layer;
import org.mapsforge.map.layer.overlay.Circle;
import org.mapsforge.map.layer.overlay.Marker;
public class MyLocationOverlay extends Layer {
private final Circle circle;
private final Marker marker;
private final LocationListener locationListener;
private static Paint getDefaultFixedPixelCircleFill() {
return getPaint(AndroidGraphicFactory.INSTANCE.createColor(255, 0, 0, 255), 0, Style.FILL);
}
private static Paint getDefaultOuterFixedPixelCircleFill(){
return getPaint(AndroidGraphicFactory.INSTANCE.createColor(30, 30, 30, 255), 0, Style.FILL);
}
private static Paint getDefaultFixedPixelCircleStroke() {
return getPaint(AndroidGraphicFactory.INSTANCE.createColor(255, 255, 255, 255), 7, Style.STROKE);
}
private static Paint getPaint(int color, int strokeWidth, Style style) {
Paint paint = AndroidGraphicFactory.INSTANCE.createPaint();
paint.setColor(color);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(style);
return paint;
}
public MyLocationOverlay(LocationListener locationListener, Drawable icon) {
this.locationListener= locationListener;
this.circle= new Circle(null, 0f, getDefaultFixedPixelCircleFill(), null);
this.marker= new Marker(null, AndroidGraphicFactory.convertToBitmap(icon), 26, 26);
}
@Override
public synchronized void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) {
if (this.circle != null) {
this.circle.draw(boundingBox, zoomLevel, canvas, topLeftPoint);
}
this.marker.draw(boundingBox, zoomLevel, canvas, topLeftPoint);
}
@Override
protected void onAdd() {
this.circle.setDisplayModel(this.displayModel);
this.marker.setDisplayModel(this.displayModel);
}
@Override
public void onDestroy() {
this.marker.onDestroy();
}
public void setPosition(double latitude, double longitude, float accuracy) {
synchronized (this) {
LatLong latLong = new LatLong(latitude, longitude);
this.marker.setLatLong(latLong);
if (this.circle != null) {
this.circle.setLatLong(latLong);
this.circle.setRadius(accuracy);
}
requestRedraw();
}
}
}

View File

@ -18,7 +18,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.location; package de.tadris.fitness.recording;
import android.app.Notification; import android.app.Notification;
import android.app.Service; import android.app.Service;

View File

@ -0,0 +1,89 @@
/*
* 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.recording;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import de.tadris.fitness.Instance;
public class PressureService extends Service {
private static final String TAG = "PressureService";
private SensorManager sensorManager;
private Instance instance;
private Sensor pressureSensor;
private PressureListener pressureListener;
private class PressureListener implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent event) {
instance.lastPressure= event.values[0];
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
instance= Instance.getInstance(this);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
pressureSensor= sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
pressureListener= new PressureListener();
if (pressureSensor != null){
instance.pressureAvailable= true;
sensorManager.registerListener(pressureListener, pressureSensor, SensorManager.SENSOR_DELAY_NORMAL);
} else {
instance.pressureAvailable= false;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
sensorManager.unregisterListener(pressureListener);
}
@Nullable @Override public IBinder onBind(Intent intent) { return null; }
}

View File

@ -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.location; package de.tadris.fitness.recording;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
@ -224,10 +224,14 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener
sample.lat= location.getLatitude(); sample.lat= location.getLatitude();
sample.lon= location.getLongitude(); sample.lon= location.getLongitude();
sample.elevation= location.getAltitude(); sample.elevation= location.getAltitude();
sample.relativeElevation= 0.0;
sample.speed= location.getSpeed(); sample.speed= location.getSpeed();
sample.relativeTime= location.getTime() - workout.start - pauseTime; sample.relativeTime= location.getTime() - workout.start - pauseTime;
sample.absoluteTime= location.getTime(); sample.absoluteTime= location.getTime();
if(Instance.getInstance(context).pressureAvailable){
sample.tmpPressure= Instance.getInstance(context).lastPressure;
}else{
sample.tmpPressure= -1;
}
synchronized (samples){ synchronized (samples){
samples.add(sample); samples.add(sample);
} }
@ -282,6 +286,10 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener
workout.comment= comment; workout.comment= comment;
} }
public boolean isPaused(){
return state == RecordingState.PAUSED;
}
enum RecordingState{ enum RecordingState{
IDLE, RUNNING, PAUSED, STOPPED IDLE, RUNNING, PAUSED, STOPPED

View File

@ -79,8 +79,8 @@ public class Exporter {
public static void importData(Context context, Uri input, ExportStatusListener listener) throws IOException{ public static void importData(Context context, Uri input, ExportStatusListener listener) throws IOException{
listener.onStatusChanged(0, context.getString(R.string.loadingFile)); listener.onStatusChanged(0, context.getString(R.string.loadingFile));
XmlMapper xmlMapper = new XmlMapper(); XmlMapper xmlMapper = new XmlMapper();
FitoTrackDataContainer container = xmlMapper.readValue(context.getContentResolver().openInputStream(input), FitoTrackDataContainer.class);
xmlMapper.configure(JsonParser.Feature.IGNORE_UNDEFINED, true); xmlMapper.configure(JsonParser.Feature.IGNORE_UNDEFINED, true);
FitoTrackDataContainer container = xmlMapper.readValue(context.getContentResolver().openInputStream(input), FitoTrackDataContainer.class);
if(container.version != 1){ if(container.version != 1){
throw new UnsupportedEncodingException("Version Code" + container.version + " is unsupported!"); throw new UnsupportedEncodingException("Version Code" + container.version + " is unsupported!");

View File

@ -1,5 +1,25 @@
/*
* 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.export; package de.tadris.fitness.util.export;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List; import java.util.List;
@ -8,6 +28,7 @@ import de.tadris.fitness.data.Workout;
import de.tadris.fitness.data.WorkoutSample; import de.tadris.fitness.data.WorkoutSample;
@JacksonXmlRootElement(localName = "fito-track") @JacksonXmlRootElement(localName = "fito-track")
@JsonIgnoreProperties(ignoreUnknown = true)
public class FitoTrackDataContainer { public class FitoTrackDataContainer {
int version; int version;

View File

@ -63,6 +63,12 @@
<string name="workoutTotalEnergy">Total Energy</string> <string name="workoutTotalEnergy">Total Energy</string>
<string name="workoutEnergyConsumption">Energy Consumption</string> <string name="workoutEnergyConsumption">Energy Consumption</string>
<string name="workoutAscent">Ascent</string>
<string name="workoutDescent">Descent</string>
<string name="height">Height</string>
<string name="workoutTypeRunning">Running</string> <string name="workoutTypeRunning">Running</string>
<string name="workoutTypeWalking">Walking</string> <string name="workoutTypeWalking">Walking</string>
<string name="workoutTypeJogging">Jogging</string> <string name="workoutTypeJogging">Jogging</string>