From e5f3f9f0f72757ddf86783cdf4ef722432bcaa91 Mon Sep 17 00:00:00 2001 From: jannis Date: Tue, 3 Mar 2020 15:32:21 +0100 Subject: [PATCH 1/2] Display workouts without GPS data --- .../fitness/activity/ShowWorkoutActivity.java | 31 ++++++++++++------- .../fitness/activity/WorkoutActivity.java | 16 ++++++++-- 2 files changed, 33 insertions(+), 14 deletions(-) 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 d336847..f23df0e 100644 --- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java @@ -82,34 +82,43 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils. addKeyValue(getString(R.string.workoutDistance), UnitUtils.getDistance(workout.length), getString(R.string.workoutPace), UnitUtils.getPace(workout.avgPace)); - addTitle(getString(R.string.workoutRoute)); + if (hasSamples()) { + addTitle(getString(R.string.workoutRoute)); - addMap(); + addMap(); + + map.setClickable(false); + mapRoot.setOnClickListener(v -> startActivity(new Intent(ShowWorkoutActivity.this, ShowWorkoutMapActivity.class))); + + } - map.setClickable(false); - mapRoot.setOnClickListener(v -> startActivity(new Intent(ShowWorkoutActivity.this, ShowWorkoutMapActivity.class))); addTitle(getString(R.string.workoutSpeed)); addKeyValue(getString(R.string.workoutAvgSpeedShort), UnitUtils.getSpeed(workout.avgSpeed), getString(R.string.workoutTopSpeed), UnitUtils.getSpeed(workout.topSpeed)); - addSpeedDiagram(); + if (hasSamples()) { - speedDiagram.setOnClickListener(v -> startDiagramActivity(ShowWorkoutMapDiagramActivity.DIAGRAM_TYPE_SPEED)); + addSpeedDiagram(); + + speedDiagram.setOnClickListener(v -> startDiagramActivity(ShowWorkoutMapDiagramActivity.DIAGRAM_TYPE_SPEED)); + } addTitle(getString(R.string.workoutBurnedEnergy)); addKeyValue(getString(R.string.workoutTotalEnergy), workout.calorie + " kcal", getString(R.string.workoutEnergyConsumption), UnitUtils.getRelativeEnergyConsumption((double)workout.calorie / ((double)workout.length / 1000))); - addTitle(getString(R.string.height)); + if (hasSamples()) { + addTitle(getString(R.string.height)); - addKeyValue(getString(R.string.workoutAscent), UnitUtils.getDistance((int)workout.ascent), - getString(R.string.workoutDescent), UnitUtils.getDistance((int)workout.descent)); + addKeyValue(getString(R.string.workoutAscent), UnitUtils.getDistance((int) workout.ascent), + getString(R.string.workoutDescent), UnitUtils.getDistance((int) workout.descent)); - addHeightDiagram(); + addHeightDiagram(); - heightDiagram.setOnClickListener(v -> startDiagramActivity(ShowWorkoutMapDiagramActivity.DIAGRAM_TYPE_HEIGHT)); + heightDiagram.setOnClickListener(v -> startDiagramActivity(ShowWorkoutMapDiagramActivity.DIAGRAM_TYPE_HEIGHT)); + } } diff --git a/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java b/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java index 3bb2e2d..ba15a6b 100644 --- a/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java @@ -297,9 +297,15 @@ public abstract class WorkoutActivity extends FitoTrackActivity { return getWindowManager().getDefaultDisplay().getWidth()*3/4; } + protected boolean hasSamples() { + return samples.size() > 1; + } + @Override protected void onDestroy() { - map.destroyAll(); + if (map != null) { + map.destroyAll(); + } AndroidGraphicFactory.clearResourceMemoryCache(); super.onDestroy(); } @@ -307,12 +313,16 @@ public abstract class WorkoutActivity extends FitoTrackActivity { @Override public void onPause(){ super.onPause(); - downloadLayer.onPause(); + if (downloadLayer != null) { + downloadLayer.onPause(); + } } public void onResume(){ super.onResume(); - downloadLayer.onResume(); + if (downloadLayer != null) { + downloadLayer.onResume(); + } } @Override From 3d930cc49ed23d406aff43606bf7effe2141d128 Mon Sep 17 00:00:00 2001 From: jannis Date: Tue, 10 Mar 2020 21:13:15 +0100 Subject: [PATCH 2/2] #53 Manually add workouts --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 3 +- .../main/java/de/tadris/fitness/Instance.java | 17 +- .../activity/EnterWorkoutActivity.java | 221 ++++++++++++++++++ .../fitness/activity/InformationActivity.java | 141 +++++++++++ .../activity/ListWorkoutsActivity.java | 18 +- .../activity/RecordWorkoutActivity.java | 20 +- .../fitness/activity/SettingsActivity.java | 2 +- .../fitness/activity/ShowWorkoutActivity.java | 60 +---- .../activity/ShowWorkoutMapActivity.java | 8 +- .../ShowWorkoutMapDiagramActivity.java | 8 +- .../fitness/activity/WorkoutActivity.java | 12 +- .../de/tadris/fitness/data/AppDatabase.java | 4 +- .../java/de/tadris/fitness/data/Workout.java | 23 +- .../tadris/fitness/data/WorkoutBuilder.java | 123 ++++++++++ .../de/tadris/fitness/data/WorkoutType.java | 58 +++++ .../fitness/dialog/DatePickerFragment.java | 54 +++++ .../dialog/DurationPickerDialogFragment.java | 86 +++++++ .../dialog/SelectWorkoutTypeDialog.java | 56 +++++ .../fitness/dialog/TimePickerFragment.java | 53 +++++ .../de/tadris/fitness/map/MapManager.java | 3 +- .../fitness/map/tilesource/TileSources.java | 33 --- .../fitness/recording/WorkoutRecorder.java | 19 +- .../announcement/Announcement.java | 2 +- .../AnnouncementAverageSpeed.java | 2 +- .../announcement/AnnouncementDistance.java | 2 +- .../announcement/AnnouncementDuration.java | 2 +- .../announcement/AnnouncementGPSStatus.java | 2 +- .../announcement/AnnouncementManager.java | 2 +- .../announcement/AnnouncementMode.java | 2 +- .../announcement/VoiceAnnouncements.java | 2 +- .../fitness/util/CalorieCalculator.java | 8 +- .../de/tadris/fitness/util/ThemeManager.java | 41 ---- .../fitness/util/WorkoutTypeCalculator.java | 46 ---- .../tadris/fitness/util/gpx/GpxExporter.java | 2 +- .../tadris/fitness/view/WorkoutAdapter.java | 3 +- .../res/layout/activity_enter_workout.xml | 32 +++ .../res/layout/activity_list_workouts.xml | 10 + .../res/layout/dialog_duration_picker.xml | 43 ++++ .../main/res/layout/enter_workout_line.xml | 73 ++++++ .../select_dialog_singlechoice_material.xml | 32 +++ app/src/main/res/menu/enter_workout_menu.xml | 27 +++ app/src/main/res/values/strings.xml | 16 ++ .../tadris/fitness/CalorieCalculatorTest.java | 3 +- 44 files changed, 1128 insertions(+), 248 deletions(-) create mode 100644 app/src/main/java/de/tadris/fitness/activity/EnterWorkoutActivity.java create mode 100644 app/src/main/java/de/tadris/fitness/activity/InformationActivity.java create mode 100644 app/src/main/java/de/tadris/fitness/data/WorkoutBuilder.java create mode 100644 app/src/main/java/de/tadris/fitness/data/WorkoutType.java create mode 100644 app/src/main/java/de/tadris/fitness/dialog/DatePickerFragment.java create mode 100644 app/src/main/java/de/tadris/fitness/dialog/DurationPickerDialogFragment.java create mode 100644 app/src/main/java/de/tadris/fitness/dialog/SelectWorkoutTypeDialog.java create mode 100644 app/src/main/java/de/tadris/fitness/dialog/TimePickerFragment.java delete mode 100644 app/src/main/java/de/tadris/fitness/map/tilesource/TileSources.java rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/Announcement.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementAverageSpeed.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementDistance.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementDuration.java (97%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementGPSStatus.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementManager.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/AnnouncementMode.java (96%) rename app/src/main/java/de/tadris/fitness/{ => recording}/announcement/VoiceAnnouncements.java (99%) delete mode 100644 app/src/main/java/de/tadris/fitness/util/ThemeManager.java delete mode 100644 app/src/main/java/de/tadris/fitness/util/WorkoutTypeCalculator.java create mode 100644 app/src/main/res/layout/activity_enter_workout.xml create mode 100644 app/src/main/res/layout/dialog_duration_picker.xml create mode 100644 app/src/main/res/layout/enter_workout_line.xml create mode 100644 app/src/main/res/layout/select_dialog_singlechoice_material.xml create mode 100644 app/src/main/res/menu/enter_workout_menu.xml diff --git a/app/build.gradle b/app/build.gradle index 916f26d..20bb00f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,7 +73,7 @@ dependencies { implementation 'org.mapsforge:mapsforge-map-android:0.11.0' implementation 'com.caverock:androidsvg:1.3' - // Charts + // UI implementation 'net.sf.kxml:kxml2:2.3.0' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' implementation 'com.github.clans:fab:1.6.4' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 79648e4..81ee76d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,7 +39,8 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - + + diff --git a/app/src/main/java/de/tadris/fitness/Instance.java b/app/src/main/java/de/tadris/fitness/Instance.java index e1bda28..44afe9b 100644 --- a/app/src/main/java/de/tadris/fitness/Instance.java +++ b/app/src/main/java/de/tadris/fitness/Instance.java @@ -60,7 +60,7 @@ public class Instance { .addMigrations(new Migration(1, 2) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { - try{ + try { database.beginTransaction(); database.execSQL("ALTER table workout add descent REAL NOT NULL DEFAULT 0;"); @@ -85,7 +85,20 @@ public class Instance { database.execSQL("DROP TABLE workout_sample2"); database.setTransactionSuccessful(); - }finally { + } finally { + database.endTransaction(); + } + } + }, new Migration(2, 3) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + try { + database.beginTransaction(); + + database.execSQL("ALTER table workout add COLUMN edited INTEGER not null default 0"); + + database.setTransactionSuccessful(); + } finally { database.endTransaction(); } } diff --git a/app/src/main/java/de/tadris/fitness/activity/EnterWorkoutActivity.java b/app/src/main/java/de/tadris/fitness/activity/EnterWorkoutActivity.java new file mode 100644 index 0000000..5eedca8 --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/activity/EnterWorkoutActivity.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2020 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.activity; + +import android.content.Intent; +import android.os.Bundle; +import android.text.InputType; +import android.util.TypedValue; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import de.tadris.fitness.R; +import de.tadris.fitness.data.WorkoutBuilder; +import de.tadris.fitness.data.WorkoutType; +import de.tadris.fitness.dialog.DatePickerFragment; +import de.tadris.fitness.dialog.DurationPickerDialogFragment; +import de.tadris.fitness.dialog.SelectWorkoutTypeDialog; +import de.tadris.fitness.dialog.TimePickerFragment; +import de.tadris.fitness.util.unit.UnitUtils; + +public class EnterWorkoutActivity extends InformationActivity implements SelectWorkoutTypeDialog.WorkoutTypeSelectListener, DatePickerFragment.DatePickerCallback, TimePickerFragment.TimePickerCallback, DurationPickerDialogFragment.DurationPickListener { + + WorkoutBuilder workoutBuilder = new WorkoutBuilder(); + TextView typeTextView, dateTextView, timeTextView, durationTextView; + EditText distanceEditText, commentEditText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_enter_workout); + + initRoot(); + + addTitle(getString(R.string.info)); + setupActionBar(); + + KeyValueLine typeLine = addKeyValueLine(getString(R.string.type)); + typeTextView = typeLine.value; + typeLine.lineRoot.setOnClickListener(v -> showTypeSelection()); + + distanceEditText = new EditText(this); + distanceEditText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); + distanceEditText.setSingleLine(true); + distanceEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); + distanceEditText.setOnEditorActionListener((v, actionId, event) -> { + // If the User clicks on the finish button on the keyboard, continue by showing the date selection + if (actionId == EditorInfo.IME_ACTION_SEARCH || + actionId == EditorInfo.IME_ACTION_DONE || + event != null && + event.getAction() == KeyEvent.ACTION_DOWN && + event.getKeyCode() == KeyEvent.KEYCODE_ENTER) { + if (event == null || !event.isShiftPressed()) { + showDateSelection(); + return true; + } + } + return false; + }); + addKeyValueLine(getString(R.string.workoutDistance), distanceEditText, UnitUtils.CHOSEN_SYSTEM.getLongDistanceUnit()); + + + KeyValueLine dateLine = addKeyValueLine(getString(R.string.workoutDate)); + dateLine.lineRoot.setOnClickListener(v -> showDateSelection()); + dateTextView = dateLine.value; + + KeyValueLine timeLine = addKeyValueLine(getString(R.string.workoutStartTime)); + timeLine.lineRoot.setOnClickListener(v -> showTimeSelection()); + timeTextView = timeLine.value; + + KeyValueLine durationLine = addKeyValueLine(getString(R.string.workoutDuration)); + durationLine.lineRoot.setOnClickListener(v -> showDurationSelection()); + durationTextView = durationLine.value; + + addTitle(getString(R.string.custom)); + + commentEditText = new EditText(this); + commentEditText.setSingleLine(true); + root.addView(commentEditText); + + updateTextViews(); + } + + private void saveWorkout() { + workoutBuilder.setComment(commentEditText.getText().toString()); + try { + workoutBuilder.setLength((int) (Double.parseDouble(distanceEditText.getText().toString()) * 1000)); + } catch (NumberFormatException ignored) { + distanceEditText.requestFocus(); + distanceEditText.setError(getString(R.string.errorEnterValidNumber)); + return; + } + if (workoutBuilder.getStart().getTimeInMillis() > System.currentTimeMillis()) { + Toast.makeText(this, R.string.errorWorkoutAddFuture, Toast.LENGTH_LONG).show(); + return; + } + if (workoutBuilder.getDuration() < 1000) { + Toast.makeText(this, R.string.errorEnterValidDuration, Toast.LENGTH_LONG).show(); + return; + } + ShowWorkoutActivity.selectedWorkout = workoutBuilder.insertWorkout(this); + startActivity(new Intent(this, ShowWorkoutActivity.class)); + finish(); + } + + private void updateTextViews() { + typeTextView.setText(getString(workoutBuilder.getWorkoutType().title)); + dateTextView.setText(SimpleDateFormat.getDateInstance().format(workoutBuilder.getStart().getTime())); + timeTextView.setText(SimpleDateFormat.getTimeInstance().format(workoutBuilder.getStart().getTime())); + durationTextView.setText(UnitUtils.getHourMinuteTime(workoutBuilder.getDuration())); + } + + private void showTypeSelection() { + new SelectWorkoutTypeDialog(this, this).show(); + } + + @Override + public void onSelectWorkoutType(WorkoutType workoutType) { + workoutBuilder.setWorkoutType(workoutType); + updateTextViews(); + distanceEditText.requestFocus(); + } + + private void showDateSelection() { + DatePickerFragment fragment = new DatePickerFragment(); + fragment.callback = this; + fragment.show(getFragmentManager(), "datePicker"); + } + + @Override + public void onDatePick(int year, int month, int day) { + workoutBuilder.getStart().set(year, month, day); + updateTextViews(); + showTimeSelection(); + } + + private void showTimeSelection() { + TimePickerFragment fragment = new TimePickerFragment(); + fragment.callback = this; + fragment.show(getFragmentManager(), "timePicker"); + } + + @Override + public void onTimePick(int hour, int minute) { + workoutBuilder.getStart().set(Calendar.HOUR_OF_DAY, hour); + workoutBuilder.getStart().set(Calendar.MINUTE, minute); + workoutBuilder.getStart().set(Calendar.SECOND, 0); + updateTextViews(); + showDurationSelection(); + } + + private void showDurationSelection() { + DurationPickerDialogFragment fragment = new DurationPickerDialogFragment(this, this, workoutBuilder.getDuration()); + fragment.listener = this; + fragment.initialDuration = workoutBuilder.getDuration(); + fragment.show(); + } + + @Override + public void onDurationPick(long duration) { + workoutBuilder.setDuration(duration); + updateTextViews(); + commentEditText.requestFocus(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.enter_workout_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + switch (id) { + case R.id.actionEnterWorkoutAdd: + saveWorkout(); + return true; + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void setupActionBar() { + if (getActionBar() != null) { + getActionBar().setDisplayHomeAsUpEnabled(true); + } + } + + @Override + void initRoot() { + root = findViewById(R.id.enterWorkoutRoot); + } +} diff --git a/app/src/main/java/de/tadris/fitness/activity/InformationActivity.java b/app/src/main/java/de/tadris/fitness/activity/InformationActivity.java new file mode 100644 index 0000000..5d7de9d --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/activity/InformationActivity.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020 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.activity; + +import android.graphics.Typeface; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import de.tadris.fitness.R; + +public abstract class InformationActivity extends FitoTrackActivity { + + ViewGroup root; + + protected void addTitle(String title) { + TextView textView = new TextView(this); + textView.setText(title); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); + textView.setTextColor(getThemePrimaryColor()); + textView.setTypeface(Typeface.DEFAULT_BOLD); + textView.setAllCaps(true); + textView.setPadding(0, 20, 0, 0); + + root.addView(textView); + } + + protected TextView addText(String text, boolean themeColor) { + TextView textView = createTextView(text, themeColor); + root.addView(textView); + + return textView; + } + + protected TextView createTextView(String text) { + return createTextView(text, false); + } + + protected TextView createTextView(String text, boolean themeColor) { + TextView textView = new TextView(this); + textView.setText(text); + textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); + if (themeColor) { + textView.setTextColor(getThemePrimaryColor()); + } else { + textView.setTextColor(getResources().getColor(R.color.textLighterBlack)); + } + textView.setPadding(0, 20, 0, 0); + + return textView; + } + + protected void addKeyValue(String key1, String value1) { + addKeyValue(key1, value1, "", ""); + } + + protected void addKeyValue(String key1, String value1, String key2, String value2) { + View v = getLayoutInflater().inflate(R.layout.show_entry, root, false); + + TextView title1 = v.findViewById(R.id.v1title); + TextView title2 = v.findViewById(R.id.v2title); + TextView v1 = v.findViewById(R.id.v1value); + TextView v2 = v.findViewById(R.id.v2value); + + title1.setText(key1); + title2.setText(key2); + v1.setText(value1); + v2.setText(value2); + + root.addView(v); + } + + protected KeyValueLine addKeyValueLine(String key) { + return addKeyValueLine(key, ""); + } + + protected KeyValueLine addKeyValueLine(String key, String value) { + return addKeyValueLine(key, null, value); + } + + protected KeyValueLine addKeyValueLine(String key, @Nullable View view) { + return addKeyValueLine(key, view, ""); + } + + protected KeyValueLine addKeyValueLine(String key, @Nullable View view, String value) { + View v = getLayoutInflater().inflate(R.layout.enter_workout_line, root, false); + + TextView keyView = v.findViewById(R.id.lineKey); + TextView valueView = v.findViewById(R.id.lineValue); + LinearLayout customViewRoot = v.findViewById(R.id.lineViewRoot); + + keyView.setText(key); + valueView.setText(value); + + if (view != null) { + customViewRoot.addView(view); + } + + root.addView(v); + return new KeyValueLine(v, keyView, valueView, view); + } + + public static class KeyValueLine { + public View lineRoot; + public TextView key; + public TextView value; + public View customView; + + public KeyValueLine(View lineRoot, TextView key, TextView value, View customView) { + this.lineRoot = lineRoot; + this.key = key; + this.value = value; + this.customView = customView; + } + } + + abstract void initRoot(); + + +} 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 d0f82d0..fbf48aa 100644 --- a/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/ListWorkoutsActivity.java @@ -37,6 +37,7 @@ import com.github.clans.fab.FloatingActionMenu; import de.tadris.fitness.Instance; import de.tadris.fitness.R; import de.tadris.fitness.data.Workout; +import de.tadris.fitness.data.WorkoutType; import de.tadris.fitness.util.DialogUtils; import de.tadris.fitness.view.WorkoutAdapter; @@ -63,16 +64,17 @@ public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.Wor menu= findViewById(R.id.workoutListMenu); menu.setOnMenuButtonLongClickListener(v -> { if(workouts.length > 0){ - startRecording(workouts[0].workoutType); + startRecording(workouts[0].getWorkoutType()); return true; }else{ return false; } }); - findViewById(R.id.workoutListRecordRunning).setOnClickListener(v -> startRecording(Workout.WORKOUT_TYPE_RUNNING)); - findViewById(R.id.workoutListRecordHiking) .setOnClickListener(v -> startRecording(Workout.WORKOUT_TYPE_HIKING)); - findViewById(R.id.workoutListRecordCycling).setOnClickListener(v -> startRecording(Workout.WORKOUT_TYPE_CYCLING)); + findViewById(R.id.workoutListRecordRunning).setOnClickListener(v -> startRecording(WorkoutType.RUNNING)); + findViewById(R.id.workoutListRecordHiking).setOnClickListener(v -> startRecording(WorkoutType.HIKING)); + findViewById(R.id.workoutListRecordCycling).setOnClickListener(v -> startRecording(WorkoutType.CYCLING)); + findViewById(R.id.workoutListEnter).setOnClickListener(v -> startEnterWorkoutActivity()); checkFirstStart(); @@ -92,7 +94,13 @@ public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.Wor } } - private void startRecording(String activity) { + private void startEnterWorkoutActivity() { + menu.close(true); + final Intent intent = new Intent(this, EnterWorkoutActivity.class); + new Handler().postDelayed(() -> startActivity(intent), 300); + } + + private void startRecording(WorkoutType activity) { menu.close(true); RecordWorkoutActivity.ACTIVITY= activity; final Intent intent= new Intent(this, RecordWorkoutActivity.class); 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 6dff96e..0780910 100644 --- a/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java @@ -53,20 +53,18 @@ import java.util.List; import de.tadris.fitness.Instance; import de.tadris.fitness.R; -import de.tadris.fitness.announcement.AnnouncementGPSStatus; -import de.tadris.fitness.announcement.VoiceAnnouncements; -import de.tadris.fitness.data.Workout; +import de.tadris.fitness.data.WorkoutType; import de.tadris.fitness.map.MapManager; -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.recording.announcement.AnnouncementGPSStatus; +import de.tadris.fitness.recording.announcement.VoiceAnnouncements; import de.tadris.fitness.util.unit.UnitUtils; public class RecordWorkoutActivity extends FitoTrackActivity implements LocationListener.LocationChangeListener, WorkoutRecorder.WorkoutRecorderListener, VoiceAnnouncements.VoiceAnnouncementCallback { - public static String ACTIVITY= Workout.WORKOUT_TYPE_RUNNING; + public static WorkoutType ACTIVITY = WorkoutType.OTHER; private MapView mapView; private TileDownloadLayer downloadLayer; @@ -90,7 +88,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setTheme(ThemeManager.getThemeByWorkoutType(ACTIVITY)); + setTheme(ACTIVITY.theme); setContentView(R.layout.activity_record_workout); setTitle(R.string.recordWorkout); @@ -148,13 +146,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location private void setupMap(){ this.mapView= new MapView(this); - TileSources.Purpose purpose; - if(ACTIVITY.equals(Workout.WORKOUT_TYPE_CYCLING)){ - purpose= TileSources.Purpose.CYCLING; - }else{ - purpose= TileSources.Purpose.OUTDOOR; - } - downloadLayer= MapManager.setupMap(mapView, purpose); + downloadLayer = MapManager.setupMap(mapView); } private void updateLine(){ diff --git a/app/src/main/java/de/tadris/fitness/activity/SettingsActivity.java b/app/src/main/java/de/tadris/fitness/activity/SettingsActivity.java index b7e5225..eaa03e2 100644 --- a/app/src/main/java/de/tadris/fitness/activity/SettingsActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/SettingsActivity.java @@ -40,9 +40,9 @@ import java.io.File; import java.io.IOException; import de.tadris.fitness.R; -import de.tadris.fitness.announcement.VoiceAnnouncements; import de.tadris.fitness.export.BackupController; import de.tadris.fitness.export.RestoreController; +import de.tadris.fitness.recording.announcement.VoiceAnnouncements; import de.tadris.fitness.util.FileUtils; import de.tadris.fitness.util.unit.UnitUtils; import de.tadris.fitness.view.ProgressDialogController; 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 f23df0e..2e039ce 100644 --- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutActivity.java @@ -21,13 +21,10 @@ package de.tadris.fitness.activity; import android.app.AlertDialog; import android.content.Intent; -import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; -import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; -import android.view.View; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Spinner; @@ -66,11 +63,15 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils. initBeforeContent(); setContentView(R.layout.activity_show_workout); - root= findViewById(R.id.showWorkoutRoot); + initRoot(); initAfterContent(); - commentView = addText(getString(R.string.comment) + ": " + workout.comment); + String commentStr = getString(R.string.comment) + ": " + workout.comment; + if (workout.edited) { + commentStr = getString(R.string.workoutEdited) + "\n" + commentStr; + } + commentView = addText(commentStr, true); commentView.setOnClickListener(v -> openEditCommentDialog()); addTitle(getString(R.string.workoutTime)); @@ -150,51 +151,6 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils. } - private void addTitle(String title) { - TextView textView= new TextView(this); - textView.setText(title); - textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); - textView.setTextColor(getThemePrimaryColor()); - textView.setTypeface(Typeface.DEFAULT_BOLD); - textView.setAllCaps(true); - textView.setPadding(0, 20, 0, 0); - - root.addView(textView); - } - - private TextView addText(String text) { - TextView textView= new TextView(this); - textView.setText(text); - textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); - textView.setTextColor(getThemePrimaryColor()); - textView.setPadding(0, 20, 0, 0); - - root.addView(textView); - - return textView; - } - - private void addKeyValue(String key1, String value1) { - addKeyValue(key1, value1, "", ""); - } - - private void addKeyValue(String key1, String value1, String key2, String value2) { - View v= getLayoutInflater().inflate(R.layout.show_entry, root, false); - - TextView title1= v.findViewById(R.id.v1title); - TextView title2= v.findViewById(R.id.v2title); - TextView v1= v.findViewById(R.id.v1value); - TextView v2= v.findViewById(R.id.v2value); - - title1.setText(key1); - title2.setText(key2); - v1.setText(value1); - v2.setText(value2); - - root.addView(v); - } - - @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. @@ -308,4 +264,8 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils. return super.onOptionsItemSelected(item); } + @Override + void initRoot() { + root = findViewById(R.id.showWorkoutRoot); + } } diff --git a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapActivity.java b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapActivity.java index b801c3c..758fd6d 100644 --- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Jannis Scheibe + * Copyright (c) 2020 Jannis Scheibe * * This file is part of FitoTrack * @@ -32,7 +32,7 @@ public class ShowWorkoutMapActivity extends WorkoutActivity { initBeforeContent(); setContentView(R.layout.activity_show_workout_map); - root= findViewById(R.id.showWorkoutMapParent); + initRoot(); initAfterContent(); @@ -43,4 +43,8 @@ public class ShowWorkoutMapActivity extends WorkoutActivity { } + @Override + void initRoot() { + root = findViewById(R.id.showWorkoutMapParent); + } } diff --git a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapDiagramActivity.java b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapDiagramActivity.java index 74915c5..684e7f4 100644 --- a/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapDiagramActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/ShowWorkoutMapDiagramActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Jannis Scheibe + * Copyright (c) 2020 Jannis Scheibe * * This file is part of FitoTrack * @@ -36,7 +36,7 @@ public class ShowWorkoutMapDiagramActivity extends WorkoutActivity { initBeforeContent(); setContentView(R.layout.activity_show_workout_map_diagram); - root= findViewById(R.id.showWorkoutMapParent); + initRoot(); initAfterContent(); @@ -54,4 +54,8 @@ public class ShowWorkoutMapDiagramActivity extends WorkoutActivity { } + @Override + void initRoot() { + root = findViewById(R.id.showWorkoutMapParent); + } } \ No newline at end of file diff --git a/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java b/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java index ba15a6b..9e436fa 100644 --- a/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java +++ b/app/src/main/java/de/tadris/fitness/activity/WorkoutActivity.java @@ -55,18 +55,14 @@ 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.map.tilesource.TileSources; -import de.tadris.fitness.util.ThemeManager; -import de.tadris.fitness.util.WorkoutTypeCalculator; import de.tadris.fitness.util.unit.UnitUtils; -public abstract class WorkoutActivity extends FitoTrackActivity { +public abstract class WorkoutActivity extends InformationActivity { public static Workout selectedWorkout; List samples; Workout workout; - ViewGroup root; private Resources.Theme theme; MapView map; private TileDownloadLayer downloadLayer; @@ -79,14 +75,14 @@ public abstract class WorkoutActivity extends FitoTrackActivity { void initBeforeContent() { workout= selectedWorkout; samples= Arrays.asList(Instance.getInstance(this).db.workoutDao().getAllSamplesOfWorkout(workout.id)); - setTheme(ThemeManager.getThemeByWorkout(workout)); + setTheme(workout.getWorkoutType().theme); } void initAfterContent() { if (getActionBar() != null) { getActionBar().setDisplayHomeAsUpEnabled(true); } - setTitle(WorkoutTypeCalculator.getType(workout)); + setTitle(workout.getWorkoutType().title); theme= getTheme(); } @@ -259,7 +255,7 @@ public abstract class WorkoutActivity extends FitoTrackActivity { void addMap(){ map= new MapView(this); - downloadLayer= MapManager.setupMap(map, TileSources.Purpose.DEFAULT); + downloadLayer = MapManager.setupMap(map); WorkoutLayer workoutLayer= new WorkoutLayer(samples, getThemePrimaryColor()); map.addLayer(workoutLayer); diff --git a/app/src/main/java/de/tadris/fitness/data/AppDatabase.java b/app/src/main/java/de/tadris/fitness/data/AppDatabase.java index 73ba188..26afafb 100644 --- a/app/src/main/java/de/tadris/fitness/data/AppDatabase.java +++ b/app/src/main/java/de/tadris/fitness/data/AppDatabase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Jannis Scheibe + * Copyright (c) 2020 Jannis Scheibe * * This file is part of FitoTrack * @@ -22,7 +22,7 @@ package de.tadris.fitness.data; import androidx.room.Database; import androidx.room.RoomDatabase; -@Database(version = 2, entities = {Workout.class, WorkoutSample.class}) +@Database(version = 3, entities = {Workout.class, WorkoutSample.class}) public abstract class AppDatabase extends RoomDatabase { public abstract WorkoutDao workoutDao(); } 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 0e9f1d2..ff63079 100644 --- a/app/src/main/java/de/tadris/fitness/data/Workout.java +++ b/app/src/main/java/de/tadris/fitness/data/Workout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Jannis Scheibe + * Copyright (c) 2020 Jannis Scheibe * * This file is part of FitoTrack * @@ -19,6 +19,7 @@ package de.tadris.fitness.data; +import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; @@ -31,10 +32,6 @@ import java.util.Date; @JsonIgnoreProperties(ignoreUnknown = true) public class Workout{ - public static final String WORKOUT_TYPE_RUNNING= "running"; - public static final String WORKOUT_TYPE_HIKING= "hiking"; - public static final String WORKOUT_TYPE_CYCLING= "cycling"; - @PrimaryKey public long id; @@ -63,12 +60,12 @@ public class Workout{ public double topSpeed; /** - * Average pace of workout in km/min + * Average pace of workout in min/km */ public double avgPace; - public String workoutType; - + @ColumnInfo(name = "workoutType") + public String workoutTypeId; public float ascent; @@ -76,6 +73,8 @@ public class Workout{ public int calorie; + public boolean edited; + public String toString(){ if(comment.length() > 2){ return comment; @@ -88,5 +87,13 @@ public class Workout{ return SimpleDateFormat.getDateTimeInstance().format(new Date(start)); } + public WorkoutType getWorkoutType() { + return WorkoutType.getTypeById(workoutTypeId); + } + + public void setWorkoutType(WorkoutType workoutType) { + this.workoutTypeId = workoutType.id; + } + } \ No newline at end of file diff --git a/app/src/main/java/de/tadris/fitness/data/WorkoutBuilder.java b/app/src/main/java/de/tadris/fitness/data/WorkoutBuilder.java new file mode 100644 index 0000000..bbf801a --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/data/WorkoutBuilder.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 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.data; + +import android.content.Context; + +import java.util.Calendar; + +import de.tadris.fitness.Instance; +import de.tadris.fitness.util.CalorieCalculator; + +public class WorkoutBuilder { + + private WorkoutType workoutType; + + private Calendar start; + private long duration; + + private int length; + + private String comment; + + public WorkoutBuilder() { + workoutType = WorkoutType.RUNNING; + start = Calendar.getInstance(); + duration = 1000L * 60 * 10; + length = 500; + comment = ""; + } + + public Workout create(Context context) { + Workout workout = new Workout(); + + // Calculate values + workout.start = start.getTimeInMillis(); + workout.end = workout.start + workout.duration; + + workout.id = workout.start; + workout.setWorkoutType(workoutType); + + workout.duration = duration; + workout.pauseDuration = 0; + + workout.length = length; + + workout.avgSpeed = (double) length / (double) (duration / 1000); + workout.topSpeed = 0; + workout.avgPace = ((double) workout.duration / 1000 / 60) / ((double) workout.length / 1000); + + workout.ascent = 0; + workout.descent = 0; + + workout.calorie = CalorieCalculator.calculateCalories(workout, Instance.getInstance(context).userPreferences.getUserWeight()); + workout.comment = comment; + + workout.edited = true; + + return workout; + } + + public Workout insertWorkout(Context context) { + Workout workout = create(context); + Instance.getInstance(context).db.workoutDao().insertWorkout(workout); + return workout; + } + + public WorkoutType getWorkoutType() { + return workoutType; + } + + public void setWorkoutType(WorkoutType workoutType) { + this.workoutType = workoutType; + } + + public Calendar getStart() { + return start; + } + + public void setStart(Calendar start) { + this.start = start; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} diff --git a/app/src/main/java/de/tadris/fitness/data/WorkoutType.java b/app/src/main/java/de/tadris/fitness/data/WorkoutType.java new file mode 100644 index 0000000..d316bcc --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/data/WorkoutType.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 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.data; + +import androidx.annotation.StringRes; +import androidx.annotation.StyleRes; + +import de.tadris.fitness.R; + +public enum WorkoutType { + + RUNNING("running", R.string.workoutTypeRunning, 7, true, R.style.Running), + HIKING("hiking", R.string.workoutTypeHiking, 7, true, R.style.Hiking), + CYCLING("cycling", R.string.workoutTypeCycling, 12, true, R.style.Bicycling), + OTHER("other", R.string.workoutTypeOther, 7, true, R.style.AppTheme); + + public String id; + public @StringRes + int title; + public int minDistance; // Minimum distance between samples + public boolean hasGPS; + public @StyleRes + int theme; + + WorkoutType(String id, int title, int minDistance, boolean hasGPS, int theme) { + this.id = id; + this.title = title; + this.minDistance = minDistance; + this.hasGPS = hasGPS; + this.theme = theme; + } + + public static WorkoutType getTypeById(String id) { + for (WorkoutType type : values()) { + if (type.id.equals(id)) { + return type; + } + } + return OTHER; + } +} diff --git a/app/src/main/java/de/tadris/fitness/dialog/DatePickerFragment.java b/app/src/main/java/de/tadris/fitness/dialog/DatePickerFragment.java new file mode 100644 index 0000000..f137420 --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/dialog/DatePickerFragment.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 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.dialog; + +import android.app.DatePickerDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.os.Bundle; +import android.widget.DatePicker; + +import java.util.Calendar; + +public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { + + public DatePickerCallback callback; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Use the current date as the default date in the picker + final Calendar c = Calendar.getInstance(); + c.setTimeInMillis(System.currentTimeMillis()); + int year = c.get(Calendar.YEAR); + int month = c.get(Calendar.MONTH); + int day = c.get(Calendar.DAY_OF_MONTH); + + // Create a new instance of DatePickerDialog and return it + return new DatePickerDialog(getActivity(), this, year, month, day); + } + + public void onDateSet(DatePicker view, int year, int month, int day) { + callback.onDatePick(year, month, day); + } + + public interface DatePickerCallback { + void onDatePick(int year, int month, int day); + } +} \ No newline at end of file diff --git a/app/src/main/java/de/tadris/fitness/dialog/DurationPickerDialogFragment.java b/app/src/main/java/de/tadris/fitness/dialog/DurationPickerDialogFragment.java new file mode 100644 index 0000000..f70429e --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/dialog/DurationPickerDialogFragment.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 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.dialog; + + +import android.app.Activity; +import android.app.AlertDialog; +import android.view.View; +import android.widget.NumberPicker; + +import de.tadris.fitness.R; + +public class DurationPickerDialogFragment { + + public Activity context; + public DurationPickListener listener; + public long initialDuration; + + public DurationPickerDialogFragment(Activity context, DurationPickListener listener, long initialDuration) { + this.context = context; + this.listener = listener; + this.initialDuration = initialDuration; + } + + public void show() { + final AlertDialog.Builder d = new AlertDialog.Builder(context); + d.setTitle(R.string.setDuration); + View v = context.getLayoutInflater().inflate(R.layout.dialog_duration_picker, null); + NumberPicker hours = v.findViewById(R.id.durationPickerHours); + hours.setFormatter(value -> value + " " + context.getString(R.string.timeHourShort)); + hours.setMinValue(0); + hours.setMaxValue(60); + hours.setValue(getInitialHours()); + + NumberPicker minutes = v.findViewById(R.id.durationPickerMinutes); + minutes.setFormatter(value -> value + " " + context.getString(R.string.timeMinuteShort)); + minutes.setMinValue(0); + minutes.setMaxValue(60); + minutes.setValue(getInitialMinutes()); + + d.setView(v); + + d.setNegativeButton(R.string.cancel, null); + d.setPositiveButton(R.string.okay, (dialog, which) -> { + listener.onDurationPick(getMillisFromPick(hours.getValue(), minutes.getValue())); + }); + + d.create().show(); + } + + private int getInitialHours() { + return (int) (initialDuration / 1000 / 60 / 60); + } + + private int getInitialMinutes() { + return (int) (initialDuration / 1000 / 60 % 60); + } + + private static long getMillisFromPick(int hours, int minutes) { + long minuteInMillis = 1000L * 60; + long hourInMillis = minuteInMillis * 60; + return hours * hourInMillis + minutes * minuteInMillis; + } + + public interface DurationPickListener { + void onDurationPick(long duration); + } + +} diff --git a/app/src/main/java/de/tadris/fitness/dialog/SelectWorkoutTypeDialog.java b/app/src/main/java/de/tadris/fitness/dialog/SelectWorkoutTypeDialog.java new file mode 100644 index 0000000..e601b68 --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/dialog/SelectWorkoutTypeDialog.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 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.dialog; + +import android.app.Activity; +import android.app.AlertDialog; +import android.widget.ArrayAdapter; + +import de.tadris.fitness.R; +import de.tadris.fitness.data.WorkoutType; + +public class SelectWorkoutTypeDialog { + + private Activity context; + private WorkoutTypeSelectListener listener; + private WorkoutType[] options; + + public SelectWorkoutTypeDialog(Activity context, WorkoutTypeSelectListener listener) { + this.context = context; + this.listener = listener; + this.options = WorkoutType.values(); + } + + public void show() { + AlertDialog.Builder builderSingle = new AlertDialog.Builder(context); + + final ArrayAdapter arrayAdapter = new ArrayAdapter<>(context, R.layout.select_dialog_singlechoice_material); + for (WorkoutType type : options) { + arrayAdapter.add(context.getString(type.title)); + } + + builderSingle.setAdapter(arrayAdapter, (dialog, which) -> listener.onSelectWorkoutType(options[which])); + builderSingle.show(); + } + + public interface WorkoutTypeSelectListener { + void onSelectWorkoutType(WorkoutType workoutType); + } +} diff --git a/app/src/main/java/de/tadris/fitness/dialog/TimePickerFragment.java b/app/src/main/java/de/tadris/fitness/dialog/TimePickerFragment.java new file mode 100644 index 0000000..9cf38fa --- /dev/null +++ b/app/src/main/java/de/tadris/fitness/dialog/TimePickerFragment.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 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.dialog; + +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.TimePickerDialog; +import android.os.Bundle; +import android.text.format.DateFormat; +import android.widget.TimePicker; + +import java.util.Calendar; + +public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { + + public TimePickerCallback callback; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Use the current time as the default values for the picker + final Calendar c = Calendar.getInstance(); + int hour = c.get(Calendar.HOUR_OF_DAY); + int minute = c.get(Calendar.MINUTE); + + // Create a new instance of TimePickerDialog and return it + return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity())); + } + + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + callback.onTimePick(hourOfDay, minute); + } + + public interface TimePickerCallback { + void onTimePick(int hour, int minute); + } +} \ No newline at end of file diff --git a/app/src/main/java/de/tadris/fitness/map/MapManager.java b/app/src/main/java/de/tadris/fitness/map/MapManager.java index 498d06e..75d85bd 100644 --- a/app/src/main/java/de/tadris/fitness/map/MapManager.java +++ b/app/src/main/java/de/tadris/fitness/map/MapManager.java @@ -30,11 +30,10 @@ import de.tadris.fitness.map.tilesource.FitoTrackTileSource; import de.tadris.fitness.map.tilesource.HumanitarianTileSource; import de.tadris.fitness.map.tilesource.MapnikTileSource; import de.tadris.fitness.map.tilesource.ThunderforestTileSource; -import de.tadris.fitness.map.tilesource.TileSources; public class MapManager { - public static TileDownloadLayer setupMap(MapView mapView, TileSources.Purpose purpose){ + public static TileDownloadLayer setupMap(MapView mapView) { FitoTrackTileSource tileSource; String chosenTileLayer= Instance.getInstance(mapView.getContext()).userPreferences.getMapStyle(); diff --git a/app/src/main/java/de/tadris/fitness/map/tilesource/TileSources.java b/app/src/main/java/de/tadris/fitness/map/tilesource/TileSources.java deleted file mode 100644 index 38d328e..0000000 --- a/app/src/main/java/de/tadris/fitness/map/tilesource/TileSources.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 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.map.tilesource; - - -public class TileSources { - - public static FitoTrackTileSource[] tileSources= new FitoTrackTileSource[]{ - MapnikTileSource.INSTANCE, HumanitarianTileSource.INSTANCE, ThunderforestTileSource.OUTDOORS, ThunderforestTileSource.CYCLE_MAP - }; - - public enum Purpose{ - DEFAULT, OUTDOOR, CYCLING - } - -} diff --git a/app/src/main/java/de/tadris/fitness/recording/WorkoutRecorder.java b/app/src/main/java/de/tadris/fitness/recording/WorkoutRecorder.java index 286f912..4280f44 100644 --- a/app/src/main/java/de/tadris/fitness/recording/WorkoutRecorder.java +++ b/app/src/main/java/de/tadris/fitness/recording/WorkoutRecorder.java @@ -32,21 +32,11 @@ import java.util.List; import de.tadris.fitness.Instance; import de.tadris.fitness.data.Workout; import de.tadris.fitness.data.WorkoutSample; +import de.tadris.fitness.data.WorkoutType; import de.tadris.fitness.util.CalorieCalculator; public class WorkoutRecorder implements LocationListener.LocationChangeListener { - private static int getMinDistance(String workoutType){ - switch (workoutType){ - case Workout.WORKOUT_TYPE_HIKING: - case Workout.WORKOUT_TYPE_RUNNING: - return 8; - case Workout.WORKOUT_TYPE_CYCLING: - return 15; - default: return 10; - } - } - private static final int PAUSE_TIME= 10000; /** @@ -72,17 +62,18 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener private final WorkoutRecorderListener workoutRecorderListener; private GpsState gpsState= GpsState.SIGNAL_LOST; - public WorkoutRecorder(Context context, String workoutType, WorkoutRecorderListener workoutRecorderListener) { + public WorkoutRecorder(Context context, WorkoutType workoutType, WorkoutRecorderListener workoutRecorderListener) { this.context= context; this.state= RecordingState.IDLE; this.workoutRecorderListener = workoutRecorderListener; this.workout= new Workout(); + workout.edited = false; // Default values this.workout.comment= ""; - this.workout.workoutType= workoutType; + this.workout.setWorkoutType(workoutType); } public void start(){ @@ -214,7 +205,7 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener WorkoutSample lastSample= samples.get(samples.size() - 1); distance= LocationListener.locationToLatLong(location).sphericalDistance(new LatLong(lastSample.lat, lastSample.lon)); long timediff= lastSample.absoluteTime - location.getTime(); - if(distance < getMinDistance(workout.workoutType) && timediff < 500){ + if (distance < workout.getWorkoutType().minDistance && timediff < 500) { return; } } diff --git a/app/src/main/java/de/tadris/fitness/announcement/Announcement.java b/app/src/main/java/de/tadris/fitness/recording/announcement/Announcement.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/Announcement.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/Announcement.java index 6ad1232..0a0cd6e 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/Announcement.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/Announcement.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; import android.preference.PreferenceManager; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementAverageSpeed.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementAverageSpeed.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementAverageSpeed.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementAverageSpeed.java index 7d163b6..27f7a79 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementAverageSpeed.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementAverageSpeed.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementDistance.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDistance.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementDistance.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDistance.java index 634e41c..751372b 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementDistance.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDistance.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementDuration.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDuration.java similarity index 97% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementDuration.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDuration.java index d4abfe4..5329bda 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementDuration.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementDuration.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementGPSStatus.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementGPSStatus.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementGPSStatus.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementGPSStatus.java index 9055e90..116570e 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementGPSStatus.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementGPSStatus.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementManager.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementManager.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementManager.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementManager.java index a59828f..9da2044 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementManager.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementManager.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; diff --git a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementMode.java b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementMode.java similarity index 96% rename from app/src/main/java/de/tadris/fitness/announcement/AnnouncementMode.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementMode.java index d2de2fd..01aeff3 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/AnnouncementMode.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/AnnouncementMode.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; import android.preference.PreferenceManager; diff --git a/app/src/main/java/de/tadris/fitness/announcement/VoiceAnnouncements.java b/app/src/main/java/de/tadris/fitness/recording/announcement/VoiceAnnouncements.java similarity index 99% rename from app/src/main/java/de/tadris/fitness/announcement/VoiceAnnouncements.java rename to app/src/main/java/de/tadris/fitness/recording/announcement/VoiceAnnouncements.java index 5bf90b8..0b34781 100644 --- a/app/src/main/java/de/tadris/fitness/announcement/VoiceAnnouncements.java +++ b/app/src/main/java/de/tadris/fitness/recording/announcement/VoiceAnnouncements.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package de.tadris.fitness.announcement; +package de.tadris.fitness.recording.announcement; import android.content.Context; import android.media.AudioManager; diff --git a/app/src/main/java/de/tadris/fitness/util/CalorieCalculator.java b/app/src/main/java/de/tadris/fitness/util/CalorieCalculator.java index ebfb002..307f793 100644 --- a/app/src/main/java/de/tadris/fitness/util/CalorieCalculator.java +++ b/app/src/main/java/de/tadris/fitness/util/CalorieCalculator.java @@ -20,6 +20,7 @@ package de.tadris.fitness.util; import de.tadris.fitness.data.Workout; +import de.tadris.fitness.data.WorkoutType; public class CalorieCalculator { @@ -47,12 +48,11 @@ public class CalorieCalculator { */ private static double getMET(Workout workout) { double speedInKmh= workout.avgSpeed * 3.6; - if(workout.workoutType.equals(Workout.WORKOUT_TYPE_RUNNING) || workout.workoutType.equals(Workout.WORKOUT_TYPE_HIKING)){ - // This is a linear graph based on the website linked above + WorkoutType type = workout.getWorkoutType(); + if (type == WorkoutType.RUNNING || type == WorkoutType.HIKING) { return Math.max(1.5, speedInKmh*1.117 - 2.1906); } - if(workout.workoutType.equals(Workout.WORKOUT_TYPE_CYCLING)){ - // This is a linear graph based on the website linked above + if (type == WorkoutType.CYCLING) { return Math.max(3, (speedInKmh-10) / 1.5); } return -1; diff --git a/app/src/main/java/de/tadris/fitness/util/ThemeManager.java b/app/src/main/java/de/tadris/fitness/util/ThemeManager.java deleted file mode 100644 index 19f00bf..0000000 --- a/app/src/main/java/de/tadris/fitness/util/ThemeManager.java +++ /dev/null @@ -1,41 +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 de.tadris.fitness.R; -import de.tadris.fitness.data.Workout; - -public class ThemeManager { - - public static int getThemeByWorkoutType(String type){ - switch (type){ - case Workout.WORKOUT_TYPE_RUNNING: return R.style.Running; - case Workout.WORKOUT_TYPE_CYCLING: return R.style.Bicycling; - case Workout.WORKOUT_TYPE_HIKING: return R.style.Hiking; - default: return R.style.AppTheme; - } - } - - public static int getThemeByWorkout(Workout workout){ - return getThemeByWorkoutType(workout.workoutType); - } - -} - diff --git a/app/src/main/java/de/tadris/fitness/util/WorkoutTypeCalculator.java b/app/src/main/java/de/tadris/fitness/util/WorkoutTypeCalculator.java deleted file mode 100644 index 6e8ac7c..0000000 --- a/app/src/main/java/de/tadris/fitness/util/WorkoutTypeCalculator.java +++ /dev/null @@ -1,46 +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 de.tadris.fitness.R; -import de.tadris.fitness.data.Workout; - -public class WorkoutTypeCalculator { - - public static int getType(Workout workout){ - if(workout.workoutType.equals(Workout.WORKOUT_TYPE_RUNNING)){ - if(workout.avgSpeed < 1.9){ - return R.string.workoutTypeWalking; - }else if(workout.avgSpeed < 2.7){ - return R.string.workoutTypeJogging; - }else{ - return R.string.workoutTypeRunning; - } - } - if(workout.workoutType.equals(Workout.WORKOUT_TYPE_CYCLING)){ - return R.string.workoutTypeCycling; - } - if(workout.workoutType.equals(Workout.WORKOUT_TYPE_HIKING)){ - return R.string.workoutTypeHiking; - } - return R.string.workoutTypeUnknown; - } - -} diff --git a/app/src/main/java/de/tadris/fitness/util/gpx/GpxExporter.java b/app/src/main/java/de/tadris/fitness/util/gpx/GpxExporter.java index 540d783..8a5dda8 100644 --- a/app/src/main/java/de/tadris/fitness/util/gpx/GpxExporter.java +++ b/app/src/main/java/de/tadris/fitness/util/gpx/GpxExporter.java @@ -61,7 +61,7 @@ public class GpxExporter { track.cmt= workout.comment; track.desc= workout.comment; track.src= "FitoTrack"; - track.type= workout.workoutType; + track.type = workout.getWorkoutType().id; track.trkseg= new ArrayList<>(); TrackSegment segment= new TrackSegment(); diff --git a/app/src/main/java/de/tadris/fitness/view/WorkoutAdapter.java b/app/src/main/java/de/tadris/fitness/view/WorkoutAdapter.java index 33152c9..8df667c 100644 --- a/app/src/main/java/de/tadris/fitness/view/WorkoutAdapter.java +++ b/app/src/main/java/de/tadris/fitness/view/WorkoutAdapter.java @@ -32,7 +32,6 @@ import java.util.Date; import de.tadris.fitness.R; import de.tadris.fitness.data.Workout; -import de.tadris.fitness.util.WorkoutTypeCalculator; import de.tadris.fitness.util.unit.UnitUtils; public class WorkoutAdapter extends RecyclerView.Adapter{ @@ -78,7 +77,7 @@ public class WorkoutAdapter extends RecyclerView.Adapter 33){ holder.commentText.setText(workout.comment.substring(0, 30) + "..."); diff --git a/app/src/main/res/layout/activity_enter_workout.xml b/app/src/main/res/layout/activity_enter_workout.xml new file mode 100644 index 0000000..07065d1 --- /dev/null +++ b/app/src/main/res/layout/activity_enter_workout.xml @@ -0,0 +1,32 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_list_workouts.xml b/app/src/main/res/layout/activity_list_workouts.xml index f8f6c13..6ba8334 100644 --- a/app/src/main/res/layout/activity_list_workouts.xml +++ b/app/src/main/res/layout/activity_list_workouts.xml @@ -72,6 +72,16 @@ app:fab_label="@string/workoutTypeCycling" app:fab_size="normal" /> + + diff --git a/app/src/main/res/layout/dialog_duration_picker.xml b/app/src/main/res/layout/dialog_duration_picker.xml new file mode 100644 index 0000000..b1eab14 --- /dev/null +++ b/app/src/main/res/layout/dialog_duration_picker.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/enter_workout_line.xml b/app/src/main/res/layout/enter_workout_line.xml new file mode 100644 index 0000000..63a0033 --- /dev/null +++ b/app/src/main/res/layout/enter_workout_line.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/select_dialog_singlechoice_material.xml b/app/src/main/res/layout/select_dialog_singlechoice_material.xml new file mode 100644 index 0000000..c0273c0 --- /dev/null +++ b/app/src/main/res/layout/select_dialog_singlechoice_material.xml @@ -0,0 +1,32 @@ + + + diff --git a/app/src/main/res/menu/enter_workout_menu.xml b/app/src/main/res/menu/enter_workout_menu.xml new file mode 100644 index 0000000..ad7e4b5 --- /dev/null +++ b/app/src/main/res/menu/enter_workout_menu.xml @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a55932e..8ebd0c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -49,10 +49,16 @@ Minute Minutes + min Hour Hours + h and + Enter a valid number + The workout cannot be in the future + Enter a valid duration + GPS Status Voice Announcements @@ -83,6 +89,7 @@ Burned Energy Total Energy Energy Consumption + This workout has been edited. Uploading Enter Verification Code Authentication failed. @@ -102,7 +109,15 @@ Jogging Cycling Hiking + Other Unknown + Type + + Custom + Enter Workout + + Set Duration + Record Workout @@ -155,4 +170,5 @@ Share Saved to Downloads Saving failed + Info diff --git a/app/src/test/java/de/tadris/fitness/CalorieCalculatorTest.java b/app/src/test/java/de/tadris/fitness/CalorieCalculatorTest.java index d360aa8..15247c6 100644 --- a/app/src/test/java/de/tadris/fitness/CalorieCalculatorTest.java +++ b/app/src/test/java/de/tadris/fitness/CalorieCalculatorTest.java @@ -23,6 +23,7 @@ import org.junit.Assert; import org.junit.Test; import de.tadris.fitness.data.Workout; +import de.tadris.fitness.data.WorkoutType; import de.tadris.fitness.util.CalorieCalculator; public class CalorieCalculatorTest { @@ -31,7 +32,7 @@ public class CalorieCalculatorTest { public void testCalculation() { Workout workout = new Workout(); workout.avgSpeed = 2.7d; - workout.workoutType = Workout.WORKOUT_TYPE_RUNNING; + workout.setWorkoutType(WorkoutType.RUNNING); workout.duration = 1000L * 60 * 10; int calorie = CalorieCalculator.calculateCalories(workout, 80); System.out.println("Calories: " + calorie);