From 063dc6e8321f13cb9a9197c094a64d503a46ba8d Mon Sep 17 00:00:00 2001 From: Shivam Date: Sun, 19 Nov 2023 19:30:02 -0500 Subject: [PATCH] feat: Give option to the user to select which metric to show in the notification bar --- .../opentracks/TrackListActivity.java | 77 ++++++++++++++++--- ...ckRecordingServiceNotificationManager.java | 24 +++++- src/main/res/values/strings.xml | 11 ++- 3 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java index bf10ba549..574e09655 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java @@ -17,9 +17,11 @@ package de.dennisguse.opentracks; import android.app.ActivityOptions; +import android.app.AlertDialog; import android.app.SearchManager; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.database.Cursor; import android.graphics.drawable.AnimatedVectorDrawable; @@ -82,7 +84,7 @@ * @author Leif Hendrik Wilden */ public class TrackListActivity extends AbstractTrackDeleteActivity implements ConfirmDeleteDialogFragment.ConfirmDeleteCaller { - + public static String notifChoice = "speed"; private static final String TAG = TrackListActivity.class.getSimpleName(); // The following are set in onCreate @@ -99,6 +101,14 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co private GpsStatusValue gpsStatusValue = TrackRecordingService.STATUS_GPS_DEFAULT; private RecordingStatus recordingStatus = TrackRecordingService.STATUS_DEFAULT; + private static final String NOTIFICATION_PREFERENCE_KEY = "notification_preference_key"; + + // Constants for notification options + private static final int SPEED_METRIC_CHOICE = 0; + private static final int HEART_RATE_METRIC_CHOICE = 1; + private static final int DISTANCE_METRIC_CHOICE = 2; + private static final int DEFAULT_CHOICE = SPEED_METRIC_CHOICE; + // Callback when an item is selected in the contextual action mode private final ActivityUtils.ContextualActionModeCallback contextualActionModeCallback = new ActivityUtils.ContextualActionModeCallback() { @@ -244,17 +254,8 @@ public void bindView(View view, Context context, Cursor cursor) { return; } - // Not Recording -> Recording - updateGpsMenuItem(false, true); - new TrackRecordingServiceConnection((service, connection) -> { - Track.Id trackId = service.startNewTrack(); - - Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class); - newIntent.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId); - startActivity(newIntent); - - connection.unbind(this); - }).startAndBind(this, true); + // Show the notification dialog to select type of the metric to show in starting new track + showNotificationOptionsDialog(); }); viewBinding.trackListFabAction.setOnLongClickListener((view) -> { if (!recordingStatus.isRecording()) { @@ -562,4 +563,56 @@ private void onRecordingStatusChanged(RecordingStatus status) { recordingStatus = status; setFloatButton(); } + + // Add a new method for handling the start recording action + private void startRecording() { + // Not Recording -> Recording + updateGpsMenuItem(false, true); + new TrackRecordingServiceConnection((service, connection) -> { + Track.Id trackId = service.startNewTrack(); + + Intent newIntent = IntentUtils.newIntent(TrackListActivity.this, TrackRecordingActivity.class); + newIntent.putExtra(TrackRecordingActivity.EXTRA_TRACK_ID, trackId); + startActivity(newIntent); + + connection.unbind(this); + }).startAndBind(this, true); + } + + // Function to show the dialog for notification options + private void showNotificationOptionsDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.choose_notification_option) + .setItems(R.array.notification_options, (dialog, which) -> { + // Store the user's choice + saveNotificationPreference(which); + + // Update the notification based on the user's choice + updateNotification(); + + // Start recording after the user has made a choice + startRecording(); + }); + builder.create().show(); + } + + // Function to save the user's notification preference + private void saveNotificationPreference(int choice) { + SharedPreferences preferences = getPreferences(Context.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt(NOTIFICATION_PREFERENCE_KEY, choice); + editor.apply(); + } + + // Function to update the notification based on user's choice + private void updateNotification() { + SharedPreferences preferences = getPreferences(Context.MODE_PRIVATE); + int userChoice = preferences.getInt(NOTIFICATION_PREFERENCE_KEY, DEFAULT_CHOICE); + + switch (userChoice) { + case SPEED_METRIC_CHOICE -> notifChoice = "speed"; + case HEART_RATE_METRIC_CHOICE -> notifChoice = "heartRate"; + case DISTANCE_METRIC_CHOICE -> notifChoice = "distance"; + } + } } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java index 7c9eb13ee..331d06597 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java @@ -17,6 +17,7 @@ import de.dennisguse.opentracks.TrackListActivity; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.DistanceFormatter; +import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.SpeedFormatter; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.PreferencesUtils; @@ -93,9 +94,26 @@ void updateTrackPoint(Context context, TrackStatistics trackStatistics, TrackPoi previousLocationWasAccurate = currentLocationWasAccurate; } - notificationBuilder.setContentTitle(context.getString(R.string.track_distance_notification, formatter.formatDistance(trackStatistics.getTotalDistance()))); - String formattedSpeed = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(true).build(context).formatSpeed(trackPoint.getSpeed()); - notificationBuilder.setContentText(context.getString(R.string.track_speed_notification, formattedSpeed)); + switch (TrackListActivity.notifChoice) { + case "distance" -> { + notificationBuilder.setContentTitle(context.getString(R.string.track_distance_notification, formatter.formatDistance(trackStatistics.getTotalDistance()))); + } + case "speed" -> { + String formattedSpeed = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(true).build(context).formatSpeed(trackPoint.getSpeed()); + notificationBuilder.setContentTitle(context.getString(R.string.track_speed_notification, formattedSpeed)); + } + case "heartRate" -> { + if (trackPoint.hasHeartRate()) { + HeartRate heartRate = trackPoint.getHeartRate(); + String formattedHeartRate = String.valueOf(heartRate.getBPM()); + notificationBuilder.setContentTitle(context.getString(R.string.track_heart_rate_notification, formattedHeartRate)); + } else { + // Handle the case where no heart rate data is available + notificationBuilder.setContentTitle(context.getString(R.string.no_heart_rate_data)); + } + } + } + notificationBuilder.setSubText(context.getString(R.string.track_recording_notification_accuracy, formattedAccuracy)); updateNotification(); diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 0cf0a94d9..d7f87fc5f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -497,6 +497,8 @@ limitations under the License. Location accuracy: %1$s Distance: %1$s Speed: %1$s + Heart Rate: %s BPM + No heart rate data available Pace: %1$s %1$s Markers @@ -605,7 +607,6 @@ limitations under the License. per kilometer per mile per nautical mile - Current time Lap time Pace Lap speed @@ -711,4 +712,12 @@ limitations under the License. Always OpenTracks itself does not provide a map. Please install OSMDashboard to view your recordings on a map. + + + Speed + Heart Rate + Distance + + + Choose Notification Option