- SettingsActivity

- set Units and weight
- not tested
This commit is contained in:
jannis 2019-08-19 21:17:17 +02:00
parent ac223e762a
commit d0e42e3382
17 changed files with 456 additions and 81 deletions

View File

@ -1,23 +1,4 @@
<?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">
@ -35,13 +16,18 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".activity.ShowWorkoutActivity" <activity android:name=".activity.SettingsActivity"></activity>
android:screenOrientation="portrait"/> <activity
<activity android:name=".activity.RecordWorkoutActivity" android:name=".activity.ShowWorkoutActivity"
android:screenOrientation="portrait"/> android:screenOrientation="portrait" />
<activity android:name=".activity.ListWorkoutsActivity" <activity
android:screenOrientation="portrait"/> android:name=".activity.RecordWorkoutActivity"
<activity android:name=".activity.LauncherActivity" android:screenOrientation="portrait" />
<activity
android:name=".activity.ListWorkoutsActivity"
android:screenOrientation="portrait" />
<activity
android:name=".activity.LauncherActivity"
android:screenOrientation="portrait"> android:screenOrientation="portrait">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View File

@ -20,11 +20,14 @@
package de.tadris.fitness; package de.tadris.fitness;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import androidx.room.Room; import androidx.room.Room;
import de.tadris.fitness.data.AppDatabase; import de.tadris.fitness.data.AppDatabase;
import de.tadris.fitness.location.LocationListener; import de.tadris.fitness.location.LocationListener;
import de.tadris.fitness.util.unit.UnitUtils;
public class Instance { public class Instance {
@ -41,13 +44,12 @@ public class Instance {
public AppDatabase db; public AppDatabase db;
public LocationListener locationListener; public LocationListener locationListener;
public UserPreferences userPreferences;
private Instance(Context context) { private Instance(Context context) {
db = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME) db = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
.allowMainThreadQueries() .allowMainThreadQueries()
.build(); .build();
locationListener= new LocationListener(context); locationListener= new LocationListener(context);
userPreferences= new UserPreferences(); UnitUtils.setUnit(context);
} }
} }

View File

@ -1,29 +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;
public class UserPreferences {
/**
* Weight in kg
*/
public float weight= 80;
}

View File

@ -28,7 +28,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import de.tadris.fitness.data.Workout; import de.tadris.fitness.data.Workout;
import de.tadris.fitness.util.UnitUtils; import de.tadris.fitness.util.unit.UnitUtils;
public class WorkoutAdapter extends RecyclerView.Adapter<WorkoutAdapter.WorkoutViewHolder>{ public class WorkoutAdapter extends RecyclerView.Adapter<WorkoutAdapter.WorkoutViewHolder>{

View File

@ -50,8 +50,7 @@ import de.tadris.fitness.location.LocationListener;
import de.tadris.fitness.location.WorkoutRecorder; import de.tadris.fitness.location.WorkoutRecorder;
import de.tadris.fitness.map.MapManager; import de.tadris.fitness.map.MapManager;
import de.tadris.fitness.util.ThemeManager; import de.tadris.fitness.util.ThemeManager;
import de.tadris.fitness.util.UnitUtils; import de.tadris.fitness.util.unit.UnitUtils;
import de.tadris.fitness.util.WorkoutTypeCalculator;
public class RecordWorkoutActivity extends FitoTrackActivity implements LocationListener.LocationChangeListener { public class RecordWorkoutActivity extends FitoTrackActivity implements LocationListener.LocationChangeListener {

View File

@ -0,0 +1,179 @@
package de.tadris.fitness.activity;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.NumberPicker;
import androidx.core.app.NavUtils;
import de.tadris.fitness.R;
import de.tadris.fitness.util.unit.Unit;
import de.tadris.fitness.util.unit.UnitUtils;
public class SettingsActivity extends PreferenceActivity {
/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
*/
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = (preference, value) -> {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
// Set the summary to reflect the new value.
preference.setSummary(
index >= 0
? listPreference.getEntries()[index]
: null);
} else if (preference instanceof RingtonePreference) {
// For ringtone preferences, look up the correct display value
// using RingtoneManager.
if (TextUtils.isEmpty(stringValue)) {
// Empty values correspond to 'silent' (no ringtone).
preference.setSummary(R.string.pref_ringtone_silent);
} else {
Ringtone ringtone = RingtoneManager.getRingtone(
preference.getContext(), Uri.parse(stringValue));
if (ringtone == null) {
// Clear the summary if there was a lookup error.
preference.setSummary(null);
} else {
// Set the summary to reflect the new ringtone display
// name.
String name = ringtone.getTitle(preference.getContext());
preference.setSummary(name);
}
}
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.setSummary(stringValue);
}
return true;
};
/*@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.pref_headers, target);
}*/
/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
* preference title) is updated to reflect the value. The summary is also
* immediately updated upon calling this method. The exact display format is
* dependent on the type of preference.
*
* @see #sBindPreferenceSummaryToValueListener
*/
private static void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActionBar();
addPreferencesFromResource(R.xml.preferences_main);
bindPreferenceSummaryToValue(findPreference("unitSystem"));
findPreference("weight").setOnPreferenceClickListener(preference -> showWeightPicker());
}
private boolean showWeightPicker() {
final AlertDialog.Builder d = new AlertDialog.Builder(this);
final SharedPreferences preferences= PreferenceManager.getDefaultSharedPreferences(this);
d.setTitle(getString(R.string.pref_weight));
View v= getLayoutInflater().inflate(R.layout.dialog_weight_picker, null);
NumberPicker np = v.findViewById(R.id.weightPicker);
np.setMaxValue((int) UnitUtils.CHOSEN_SYSTEM.getWeightFromKilogram(150));
np.setMinValue((int) UnitUtils.CHOSEN_SYSTEM.getWeightFromKilogram(20));
np.setValue(preferences.getInt("weight", 80));
np.setFormatter(value -> value + UnitUtils.CHOSEN_SYSTEM.getWeightUnit());
np.setWrapSelectorWheel(false);
d.setView(v);
d.setNegativeButton(R.string.cancel, null);
d.setPositiveButton(R.string.okay, (DialogInterface.OnClickListener) (dialog, which) -> {
int unitValue= np.getValue();
int kilograms= (int)Math.round(UnitUtils.CHOSEN_SYSTEM.getKilogramFromUnit(unitValue));
preferences.edit().putInt("weight", kilograms).apply();
});
d.create().show();
return true;
}
/**
* Set up the {@link android.app.ActionBar}, if the API is available.
*/
private void setupActionBar() {
ActionBar actionBar = getActionBar();
if (actionBar != null) {
// Show the Up button in the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
UnitUtils.setUnit(this);
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
if (!super.onMenuItemSelected(featureId, item)) {
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
}

View File

@ -63,7 +63,7 @@ import de.tadris.fitness.data.WorkoutSample;
import de.tadris.fitness.map.MapManager; import de.tadris.fitness.map.MapManager;
import de.tadris.fitness.map.WorkoutLayer; import de.tadris.fitness.map.WorkoutLayer;
import de.tadris.fitness.util.ThemeManager; import de.tadris.fitness.util.ThemeManager;
import de.tadris.fitness.util.UnitUtils; import de.tadris.fitness.util.unit.UnitUtils;
import de.tadris.fitness.util.WorkoutTypeCalculator; import de.tadris.fitness.util.WorkoutTypeCalculator;
public class ShowWorkoutActivity extends FitoTrackActivity { public class ShowWorkoutActivity extends FitoTrackActivity {

View File

@ -0,0 +1,54 @@
package de.tadris.fitness.util.unit;
public class Imperial implements Unit {
@Override
public int getId() {
return 3;
}
@Override
public double getDistanceFromMeters(double meters) {
return meters * 1.093613d;
}
@Override
public double getDistanceFromKilometers(double kilometers) {
return kilometers * 0.62137d;
}
@Override
public double getWeightFromKilogram(double kilogram) {
return kilogram * 2.2046;
}
@Override
public double getKilogramFromUnit(double unit) {
return unit / 2.2046;
}
@Override
public double getSpeedFromMeterPerSecond(double meterPerSecond) {
return meterPerSecond*3.6*0.62137d;
}
@Override
public String getLongDistanceUnit() {
return "mi";
}
@Override
public String getShortDistanceUnit() {
return "yd";
}
@Override
public String getWeightUnit() {
return "lbs";
}
@Override
public String getSpeedUnit() {
return "mi/h";
}
}

View File

@ -0,0 +1,23 @@
package de.tadris.fitness.util.unit;
public class ImperialWithMeters extends Imperial {
@Override
public int getId() {
return 4;
}
@Override
public double getDistanceFromMeters(double meters) {
return meters;
}
@Override
public String getLongDistanceUnit() {
return "m";
}
@Override
public String getShortDistanceUnit() {
return "yd";
}
}

View File

@ -0,0 +1,54 @@
package de.tadris.fitness.util.unit;
public class Metric implements Unit{
@Override
public int getId() {
return 1;
}
@Override
public double getDistanceFromMeters(double meters) {
return meters;
}
@Override
public double getDistanceFromKilometers(double kilometers) {
return kilometers;
}
@Override
public double getWeightFromKilogram(double kilogram) {
return kilogram;
}
@Override
public double getKilogramFromUnit(double unit) {
return unit;
}
@Override
public double getSpeedFromMeterPerSecond(double meterPerSecond) {
return meterPerSecond * 3.6;
}
@Override
public String getLongDistanceUnit() {
return "km";
}
@Override
public String getShortDistanceUnit() {
return "m";
}
@Override
public String getWeightUnit() {
return "kg";
}
@Override
public String getSpeedUnit() {
return "km/h";
}
}

View File

@ -0,0 +1,19 @@
package de.tadris.fitness.util.unit;
public class MetricPhysical extends Metric{
@Override
public int getId() {
return 2;
}
@Override
public double getSpeedFromMeterPerSecond(double meterPerSecond) {
return meterPerSecond;
}
@Override
public String getSpeedUnit() {
return "m/s";
}
}

View File

@ -0,0 +1,16 @@
package de.tadris.fitness.util.unit;
public interface Unit {
int getId();
double getDistanceFromMeters(double meters);
double getDistanceFromKilometers(double kilometers);
double getWeightFromKilogram(double kilogram);
double getKilogramFromUnit(double unit);
double getSpeedFromMeterPerSecond(double meterPerSecond);
String getLongDistanceUnit();
String getShortDistanceUnit();
String getWeightUnit();
String getSpeedUnit();
}

View File

@ -17,10 +17,36 @@
* 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.util; package de.tadris.fitness.util.unit;
import android.content.Context;
import android.preference.PreferenceManager;
public class UnitUtils { public class UnitUtils {
public static final Unit UNITS_METRIC= new Metric();
public static final Unit UNITS_METRIC_PHYSICAL= new MetricPhysical();
public static final Unit UNITS_IMPERIAL_YARDS= new Imperial();
public static final Unit UNITS_IMPERIAL_METERS= new ImperialWithMeters();
public static final Unit[] supportedUnits= new Unit[] {
UNITS_METRIC, UNITS_METRIC_PHYSICAL, UNITS_IMPERIAL_YARDS, UNITS_IMPERIAL_METERS
};
public static Unit CHOSEN_SYSTEM= UNITS_METRIC;
public static void setUnit(Context context){
PreferenceManager.getDefaultSharedPreferences(context).getInt("unitSystem", UnitUtils.UNITS_METRIC.getId());
}
public static void setUnit(int id){
CHOSEN_SYSTEM= UNITS_METRIC;
for(Unit unit : supportedUnits){
if(id == unit.getId()){
CHOSEN_SYSTEM= unit;
}
}
}
public static String getHourMinuteTime(long time){ public static String getHourMinuteTime(long time){
long seks= time / 1000; long seks= time / 1000;
long mins= seks / 60; long mins= seks / 60;
@ -51,18 +77,18 @@ public class UnitUtils {
* @return Pace * @return Pace
*/ */
public static String getPace(double pace){ public static String getPace(double pace){
// TODO: use preferred unit chosen by user double one= CHOSEN_SYSTEM.getDistanceFromKilometers(1);
return round(pace, 1) + " min/km"; return round(pace / one, 1) + " min/" + CHOSEN_SYSTEM.getLongDistanceUnit();
} }
/** /**
* *CHOSEN_SYSTEM.getLongDistanceUnit()
* @param consumption consumption in kcal/km * @param consumption consumption in kcal/km
* @return * @return
*/ */
public static String getRelativeEnergyConsumption(double consumption){ public static String getRelativeEnergyConsumption(double consumption){
// TODO: use preferred unit chosen by user double one= CHOSEN_SYSTEM.getDistanceFromKilometers(1);
return round(consumption, 2) + " kcal/km"; return round(consumption / one, 2) + " kcal/" + CHOSEN_SYSTEM.getLongDistanceUnit();
} }
/** /**
@ -71,11 +97,11 @@ public class UnitUtils {
* @return String in preferred unit * @return String in preferred unit
*/ */
public static String getDistance(int distance){ public static String getDistance(int distance){
// TODO: use preferred unit chosen by user double units= CHOSEN_SYSTEM.getDistanceFromMeters(distance);
if(distance >= 1000){ if(units >= 1000){
return getDistanceInKilometers((double)distance); return round(units / 1000, 1) + " " + CHOSEN_SYSTEM.getLongDistanceUnit();
}else{ }else{
return getDistanceInMeters(distance); return (int)units + " " + CHOSEN_SYSTEM.getShortDistanceUnit();
} }
} }
@ -85,16 +111,7 @@ public class UnitUtils {
* @return speed in km/h * @return speed in km/h
*/ */
public static String getSpeed(double speed){ public static String getSpeed(double speed){
// TODO: use preferred unit chosen by user return round(CHOSEN_SYSTEM.getSpeedFromMeterPerSecond(speed), 1) + " " + CHOSEN_SYSTEM.getSpeedUnit();
return round(speed*3.6, 1) + " km/h";
}
public static String getDistanceInMeters(int distance){
return distance + " m";
}
public static String getDistanceInKilometers(double distance){
return round(distance / 1000, 1) + " km";
} }
public static double round(double d, int count){ public static double round(double d, int count){

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<NumberPicker
android:id="@+id/weightPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="30dp" />
</RelativeLayout>

View File

@ -23,6 +23,8 @@
<string name="workoutStopRecording">Stop</string> <string name="workoutStopRecording">Stop</string>
<string name="delete">Delete</string> <string name="delete">Delete</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="workoutTime">Time</string> <string name="workoutTime">Time</string>
<string name="workoutDate">Date</string> <string name="workoutDate">Date</string>
<string name="workoutDuration">Duration</string> <string name="workoutDuration">Duration</string>
@ -52,4 +54,7 @@
<string name="deleteWorkoutMessage">Do you really want to delete the workout?</string> <string name="deleteWorkoutMessage">Do you really want to delete the workout?</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="pref_weight">Your Weight</string>
<string name="pref_weight_summary">Your weight is needed to calculate the burned calories</string>
<string name="pref_unit_system">Preferred system of units</string>
</resources> </resources>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="pref_unit_systems">
<item>Metric</item>
<item>Metric Physical (m/s)</item>
<item>Imperial</item>
<item>Imperial with meters</item>
</string-array>
<integer-array name="pref_unit_system_values">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</integer-array>
</resources>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:entries="@array/pref_unit_systems"
android:entryValues="@array/pref_unit_system_values"
android:key="unitSystem"
android:title="@string/pref_unit_system" />
<Preference
android:key="weight"
android:selectAllOnFocus="true"
android:singleLine="true"
android:summary="@string/pref_weight_summary"
android:title="@string/pref_weight" />
</PreferenceScreen>