mirror of
https://github.com/russok/FitoTrack.git
synced 2025-10-28 16:22:12 -07:00
Merge branch 'master' into feature-unit_systems
# Conflicts: # app/src/main/java/de/tadris/fitness/Instance.java # app/src/main/java/de/tadris/fitness/activity/RecordWorkoutActivity.java
This commit is contained in:
commit
9b52fb0be1
@ -15,7 +15,7 @@ It is open-source and completely ad-free.
|
||||
- **View your workouts.** View general information like date, time, duration, distance, speed, pace. See your route on a map. Investigate how you performed in the speed diagram.
|
||||
- **Open-Source.** There is no advertivesment, no tracking and the source code is open and licensed under the GPLv3 .
|
||||
|
||||
see [Roadmap](https://bitbucket.org/jannis3/fitotrack/src/master/Roadmap.md) for more planned features
|
||||
see [Roadmap](https://codeberg.org/jannis/FitoTrack/src/branch/master/Roadmap.md) for more planned features
|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
27
Roadmap.md
27
Roadmap.md
@ -1,21 +1,20 @@
|
||||
# Roadmap
|
||||
|
||||
## First release
|
||||
|
||||
- design of ListWorkoutActivty
|
||||
- set title in ActionBar according to activity
|
||||
- choose workout type
|
||||
- user defined workout titles, description
|
||||
- rating of workout
|
||||
- change units
|
||||
- change weight of user
|
||||
- export to gpx file
|
||||
|
||||
## Planned features
|
||||
## Coming features
|
||||
|
||||
- measurement of height using pressure data
|
||||
- height data in diagram
|
||||
- measurement of steps using sensor data
|
||||
- upload workouts to dropbox
|
||||
- offline maps?
|
||||
|
||||
## Planned features
|
||||
|
||||
- upload workouts as GPX to dropbox
|
||||
- upload workouts as GPS trace to OpenStreetMap
|
||||
- voice feedback e.g. speaking every 10-30 minutes the general data
|
||||
- support fitnessbands
|
||||
|
||||
## Considered features
|
||||
|
||||
- running "against" other workouts
|
||||
- offline maps
|
||||
- something like a comparision to your friends
|
||||
@ -7,6 +7,7 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -35,6 +36,7 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".location.LocationListener"></service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -25,6 +25,9 @@ import android.preference.PreferenceManager;
|
||||
|
||||
import androidx.room.Room;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.tadris.fitness.data.AppDatabase;
|
||||
import de.tadris.fitness.location.LocationListener;
|
||||
import de.tadris.fitness.util.unit.UnitUtils;
|
||||
@ -43,13 +46,12 @@ public class Instance {
|
||||
}
|
||||
|
||||
public AppDatabase db;
|
||||
public LocationListener locationListener;
|
||||
public List<LocationListener.LocationChangeListener> locationChangeListeners= new ArrayList<>();
|
||||
|
||||
private Instance(Context context) {
|
||||
db = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
|
||||
.allowMainThreadQueries()
|
||||
.build();
|
||||
locationListener= new LocationListener(context);
|
||||
UnitUtils.setUnit(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,14 +22,13 @@ package de.tadris.fitness.activity;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.github.clans.fab.FloatingActionButton;
|
||||
import com.github.clans.fab.FloatingActionMenu;
|
||||
|
||||
import de.tadris.fitness.Instance;
|
||||
@ -66,8 +65,10 @@ public class ListWorkoutsActivity extends Activity implements WorkoutAdapter.Wor
|
||||
}
|
||||
|
||||
public void startRecording(String activity){
|
||||
menu.close(true);
|
||||
RecordWorkoutActivity.ACTIVITY= activity;
|
||||
startActivity(new Intent(this, RecordWorkoutActivity.class));
|
||||
final Intent intent= new Intent(this, RecordWorkoutActivity.class);
|
||||
new Handler().postDelayed(() -> startActivity(intent), 300);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* 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.
|
||||
* (at your option) any later velocationListener= new LocationListener(context);rsion.
|
||||
*
|
||||
* FitoTrack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -20,14 +20,18 @@
|
||||
package de.tadris.fitness.activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
@ -66,6 +70,7 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
boolean isResumed= false;
|
||||
private Handler mHandler= new Handler();
|
||||
PowerManager.WakeLock wakeLock;
|
||||
Intent locationListener;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -94,11 +99,16 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
|
||||
startUpdater();
|
||||
acquireWakelock();
|
||||
|
||||
Instance.getInstance(this).locationChangeListeners.add(this);
|
||||
|
||||
startListener();
|
||||
|
||||
}
|
||||
|
||||
private void acquireWakelock(){
|
||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "de.tadris.fitotrack:workout_recorder");
|
||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "de.tadris.fitotrack:workout_recorder");
|
||||
wakeLock.acquire(1000*60*120);
|
||||
}
|
||||
|
||||
@ -143,14 +153,40 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
infoViews[3].setText(getString(R.string.workoutPauseDuration), UnitUtils.getHourMinuteSecondTime(recorder.getPauseDuration()));
|
||||
}
|
||||
|
||||
private void stopAndSave(){
|
||||
private void stop(){
|
||||
recorder.stop();
|
||||
if(recorder.getSampleCount() > 3){
|
||||
showEnterDescriptionDialog();
|
||||
}else{
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAndClose(){
|
||||
if(recorder.getSampleCount() > 3){
|
||||
recorder.save();
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
private void showEnterDescriptionDialog(){
|
||||
final EditText editText= new EditText(this);
|
||||
new AlertDialog.Builder(this).setTitle(R.string.enterComment).setPositiveButton(R.string.okay, (dialog, which) -> {
|
||||
dialog.cancel();
|
||||
recorder.setComment(editText.getText().toString());
|
||||
saveAndClose();
|
||||
}).setView(editText).setCancelable(false).create().show();
|
||||
}
|
||||
|
||||
private void showAreYouSureToStopDialog(){
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.stopRecordingQuestion)
|
||||
.setMessage(R.string.stopRecordingQuestionMessage)
|
||||
.setPositiveButton(R.string.okay, (dialog, which) -> stop())
|
||||
.setNegativeButton(R.string.continue_, null)
|
||||
.create().show();
|
||||
}
|
||||
|
||||
void checkPermissions(){
|
||||
if (!hasPermission()) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 10);
|
||||
@ -165,7 +201,24 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
if (hasPermission()) {
|
||||
Instance.getInstance(this).locationListener.enableMyLocation();
|
||||
startListener();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopListener(){
|
||||
stopService(locationListener);
|
||||
}
|
||||
|
||||
public void startListener(){
|
||||
if(locationListener == null){
|
||||
locationListener= new Intent(this, LocationListener.class);
|
||||
}else{
|
||||
stopListener();
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(locationListener);
|
||||
}else{
|
||||
startService(locationListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,20 +239,20 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
if(wakeLock.isHeld()){
|
||||
wakeLock.release();
|
||||
}
|
||||
Instance.getInstance(this).locationChangeListeners.remove(this);
|
||||
stopListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
downloadLayer.onPause();
|
||||
Instance.getInstance(this).locationListener.unregisterLocationChangeListeners(this);
|
||||
isResumed= false;
|
||||
}
|
||||
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
downloadLayer.onResume();
|
||||
Instance.getInstance(this).locationListener.registerLocationChangeListeners(this);
|
||||
isResumed= true;
|
||||
}
|
||||
|
||||
@ -214,12 +267,21 @@ public class RecordWorkoutActivity extends FitoTrackActivity implements Location
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if(id == R.id.actionRecordingStop){
|
||||
stopAndSave();
|
||||
stop();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if(recorder.getSampleCount() > 3){
|
||||
showAreYouSureToStopDialog();
|
||||
}else{
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
public static class InfoViewHolder{
|
||||
TextView titleView, valueView;
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
@ -93,6 +94,11 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
||||
|
||||
root= findViewById(R.id.showWorkoutRoot);
|
||||
|
||||
addText(getString(R.string.comment) + ": " + workout.comment).setOnClickListener(v -> {
|
||||
TextView textView= (TextView)v;
|
||||
openEditCommentDialog(textView);
|
||||
});
|
||||
|
||||
addTitle(getString(R.string.workoutTime));
|
||||
addKeyValue(getString(R.string.workoutDate), getDate());
|
||||
addKeyValue(getString(R.string.workoutDuration), UnitUtils.getHourMinuteSecondTime(workout.duration),
|
||||
@ -120,6 +126,21 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
||||
|
||||
}
|
||||
|
||||
void openEditCommentDialog(final TextView change){
|
||||
final EditText editText= new EditText(this);
|
||||
editText.setText(workout.comment);
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.enterComment)
|
||||
.setPositiveButton(R.string.okay, (dialog, which) -> changeComment(editText.getText().toString(), change))
|
||||
.setView(editText).create().show();
|
||||
}
|
||||
|
||||
void changeComment(String comment, TextView onChange){
|
||||
workout.comment= comment;
|
||||
Instance.getInstance(this).db.workoutDao().updateWorkout(workout);
|
||||
onChange.setText(getString(R.string.comment) + ": " + workout.comment);
|
||||
}
|
||||
|
||||
String getDate(){
|
||||
return SimpleDateFormat.getDateInstance().format(new Date(workout.start));
|
||||
}
|
||||
@ -137,6 +158,18 @@ public class ShowWorkoutActivity extends FitoTrackActivity {
|
||||
root.addView(textView);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void addKeyValue(String key1, String value1){
|
||||
addKeyValue(key1, value1, "", "");
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ public class Workout{
|
||||
|
||||
public long pauseDuration;
|
||||
|
||||
public String comment;
|
||||
|
||||
/**
|
||||
* Length of workout in meters
|
||||
*/
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
package de.tadris.fitness.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -34,6 +35,16 @@ public class WorkoutManager {
|
||||
|
||||
workout.id= System.currentTimeMillis();
|
||||
|
||||
// Delete Samples with same time
|
||||
for(int i= samples.size()-2; i >= 0; i--){
|
||||
WorkoutSample sample= samples.get(i);
|
||||
WorkoutSample lastSample= samples.get(i+1);
|
||||
if(sample.absoluteTime == lastSample.absoluteTime){
|
||||
samples.remove(lastSample);
|
||||
Log.i("WorkoutManager", "Removed samples at " + sample.absoluteTime + " rel: " + sample.relativeTime + "; " + lastSample.relativeTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculating values
|
||||
double length= 0;
|
||||
for(int i= 1; i < samples.size(); i++){
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Jannis Scheibe <jannis@tadris.de>
|
||||
*
|
||||
@ -19,23 +20,23 @@
|
||||
|
||||
package de.tadris.fitness.location;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Notification;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mapsforge.core.model.LatLong;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import de.tadris.fitness.Instance;
|
||||
import de.tadris.fitness.R;
|
||||
import de.tadris.fitness.util.NotificationHelper;
|
||||
|
||||
public class LocationListener implements android.location.LocationListener {
|
||||
|
||||
public static LatLong static_lastLocation;
|
||||
public class LocationListener extends Service {
|
||||
|
||||
/**
|
||||
* @param location the location whose geographical coordinates should be converted.
|
||||
@ -45,113 +46,95 @@ public class LocationListener implements android.location.LocationListener {
|
||||
return new LatLong(location.getLatitude(), location.getLongitude());
|
||||
}
|
||||
|
||||
private Context activity;
|
||||
private Location lastLocation;
|
||||
private final LocationManager locationManager;
|
||||
private boolean myLocationEnabled;
|
||||
private static final String TAG = "LocationListener";
|
||||
private LocationManager mLocationManager = null;
|
||||
private static final int LOCATION_INTERVAL = 1000;
|
||||
|
||||
public LocationListener(Context context) {
|
||||
super();
|
||||
this.activity= context;
|
||||
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
}
|
||||
private class LocationChangedListener implements android.location.LocationListener {
|
||||
Location mLastLocation;
|
||||
|
||||
|
||||
/**
|
||||
* Stops the receiving of location updates. Has no effect if location updates are already disabled.
|
||||
*/
|
||||
public synchronized void disableMyLocation() {
|
||||
if (this.myLocationEnabled) {
|
||||
this.myLocationEnabled = false;
|
||||
try {
|
||||
this.locationManager.removeUpdates(this);
|
||||
} catch (RuntimeException runtimeException) {
|
||||
// do we need to catch security exceptions for this call on Android 6?
|
||||
}
|
||||
public LocationChangedListener(String provider) {
|
||||
Log.i(TAG, "LocationListener " + provider);
|
||||
mLastLocation = new Location(provider);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void enableMyLocation() {
|
||||
enableBestAvailableProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the most-recently received location fix (might be null).
|
||||
*/
|
||||
public synchronized Location getLastLocation() {
|
||||
return this.lastLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the receiving of location updates is currently enabled, false otherwise.
|
||||
*/
|
||||
public synchronized boolean isMyLocationEnabled() {
|
||||
return this.myLocationEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
|
||||
synchronized (this) {
|
||||
this.lastLocation = location;
|
||||
|
||||
LatLong latLong = locationToLatLong(location);
|
||||
static_lastLocation= latLong;
|
||||
|
||||
for(LocationChangeListener listener : this.locationChangeListeners){
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
Log.i(TAG, "onLocationChanged: " + location);
|
||||
mLastLocation.set(location);
|
||||
for(LocationChangeListener listener : Instance.getInstance(getBaseContext()).locationChangeListeners){
|
||||
listener.onLocationChange(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
enableBestAvailableProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
enableBestAvailableProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
private void enableBestAvailableProvider() {
|
||||
disableMyLocation();
|
||||
|
||||
boolean result = false;
|
||||
for (String provider : this.locationManager.getProviders(true)) {
|
||||
if (LocationManager.GPS_PROVIDER.equals(provider)) {
|
||||
result = true;
|
||||
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
this.locationManager.requestLocationUpdates(provider, 0, 0, this);
|
||||
Location location= this.locationManager.getLastKnownLocation(provider);
|
||||
if(location != null){
|
||||
onLocationChanged(location);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
Log.i(TAG, "onProviderDisabled: " + provider);
|
||||
}
|
||||
this.myLocationEnabled = result;
|
||||
}
|
||||
|
||||
private List<LocationChangeListener> locationChangeListeners= new ArrayList<>();
|
||||
|
||||
public void registerLocationChangeListeners(LocationChangeListener listener){
|
||||
if(locationChangeListeners.size() == 0){
|
||||
enableMyLocation();
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
Log.i(TAG, "onProviderEnabled: " + provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
Log.i(TAG, "onStatusChanged: " + provider);
|
||||
}
|
||||
locationChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
public void unregisterLocationChangeListeners(LocationChangeListener listener){
|
||||
locationChangeListeners.remove(listener);
|
||||
if(locationChangeListeners.size() == 0){
|
||||
disableMyLocation();
|
||||
LocationChangedListener gpsListener= new LocationChangedListener(LocationManager.GPS_PROVIDER);
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i(TAG, "onStartCommand");
|
||||
super.onStartCommand(intent, flags, startId);
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(this)
|
||||
.setContentTitle(getText(R.string.trackerRunning))
|
||||
.setContentText(getText(R.string.trackerRunningMessage));
|
||||
//.setSmallIcon(R.drawable.icon)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
NotificationHelper.createChannels(this);
|
||||
builder.setChannelId(NotificationHelper.CHANNEL_WORKOUT);
|
||||
}
|
||||
|
||||
startForeground(10, builder.build());
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.i(TAG, "onCreate");
|
||||
initializeLocationManager();
|
||||
try {
|
||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, 0, gpsListener);
|
||||
} catch (java.lang.SecurityException ex) {
|
||||
Log.i(TAG, "fail to request location update, ignore", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.i(TAG, "onDestroy");
|
||||
super.onDestroy();
|
||||
if (mLocationManager != null) {
|
||||
mLocationManager.removeUpdates(gpsListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeLocationManager() {
|
||||
Log.i(TAG, "initializeLocationManager");
|
||||
if (mLocationManager == null) {
|
||||
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener
|
||||
Log.i("Recorder", "Start");
|
||||
workout.start= System.currentTimeMillis();
|
||||
resume();
|
||||
Instance.getInstance(context).locationListener.registerLocationChangeListeners(this);
|
||||
Instance.getInstance(context).locationChangeListeners.add(this);
|
||||
startWatchdog();
|
||||
}else if(state == RecordingState.PAUSED){
|
||||
resume();
|
||||
@ -143,7 +143,7 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener
|
||||
workout.duration= time;
|
||||
workout.pauseDuration= pauseTime;
|
||||
state= RecordingState.STOPPED;
|
||||
Instance.getInstance(context).locationListener.unregisterLocationChangeListeners(this);
|
||||
Instance.getInstance(context).locationChangeListeners.remove(this);
|
||||
}
|
||||
|
||||
public void save(){
|
||||
@ -245,6 +245,10 @@ public class WorkoutRecorder implements LocationListener.LocationChangeListener
|
||||
}
|
||||
}
|
||||
|
||||
public void setComment(String comment){
|
||||
workout.comment= comment;
|
||||
}
|
||||
|
||||
|
||||
enum RecordingState{
|
||||
IDLE, RUNNING, PAUSED, STOPPED
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Jannis Scheibe <jannis@tadris.de>
|
||||
*
|
||||
* This file is part of FitoTrack
|
||||
*
|
||||
* FitoTrack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* FitoTrack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.tadris.fitness.util;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import de.tadris.fitness.R;
|
||||
|
||||
public class NotificationHelper {
|
||||
|
||||
public static String CHANNEL_WORKOUT= "workout";
|
||||
|
||||
public static void createChannels(Context context){
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel(context, CHANNEL_WORKOUT, R.string.trackingInfo, R.string.trackingInfoDescription, NotificationManager.IMPORTANCE_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createNotificationChannel(Context context, String id, int nameId, int descriptionId, int importance) {
|
||||
// Create the NotificationChannel, but only on API 26+ because
|
||||
// the NotificationChannel class is new and not in the support library
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
CharSequence name = context.getString(nameId);
|
||||
String description = context.getString(descriptionId);
|
||||
NotificationChannel channel = new NotificationChannel(id, name, importance);
|
||||
channel.setDescription(description);
|
||||
// Register the channel with the system; you can't change the importance
|
||||
// or other notification behaviors after this
|
||||
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -50,9 +50,25 @@
|
||||
|
||||
<string name="recordWorkout">Record Workout</string>
|
||||
|
||||
<string name="comment">Comment</string>
|
||||
<string name="enterComment">Enter Comment</string>
|
||||
<string name="okay">Okay</string>
|
||||
|
||||
<string name="stopRecordingQuestion">Stop Recording?</string>
|
||||
<string name="stopRecordingQuestionMessage">Do you really want to stop the recording?</string>
|
||||
|
||||
<!-- leave the underscore because "continue" is a java command -->
|
||||
<string name="continue_">Continue</string>
|
||||
|
||||
<string name="deleteWorkout">Delete Workout</string>
|
||||
<string name="deleteWorkoutMessage">Do you really want to delete the workout?</string>
|
||||
|
||||
<string name="trackerRunning">Tracker is running</string>
|
||||
<string name="trackerRunningMessage">Your workout is being recorded</string>
|
||||
|
||||
<string name="trackingInfo">Tracking Info</string>
|
||||
<string name="trackingInfoDescription">Info about the tracker running</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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user