From 5605e33c3238941e798da548fad99886d61648bd Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 5 Feb 2021 19:31:57 +0500 Subject: [PATCH 1/4] Add bottom sheet dialogs to clear recoderd data and stop trip recording --- .../bottom_sheet_item_button_with_icon.xml | 69 +++++++ OsmAnd/res/values/sizes.xml | 2 + OsmAnd/res/values/strings.xml | 4 + .../ClearRecordedDataBottomSheetFragment.java | 160 +++++++++++++++ .../StopTrackRecordingBottomFragment.java | 187 ++++++++++++++++++ 5 files changed, 422 insertions(+) create mode 100644 OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java diff --git a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml new file mode 100644 index 0000000000..9b2b395ccb --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/sizes.xml b/OsmAnd/res/values/sizes.xml index a086849297..afdc8438af 100644 --- a/OsmAnd/res/values/sizes.xml +++ b/OsmAnd/res/values/sizes.xml @@ -413,4 +413,6 @@ 32dp 24dp + + 0dp \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a15fb40cbd..905a947661 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,10 @@ --> + Are you sure you want to stop recording?\nAll unsaved data will be lost. + Track recording stopped + Save and stop recording + Stop without saving Login to OpenPlaceReviews Use test.openplacereviews.org OpenPlaceReviews diff --git a/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java new file mode 100644 index 0000000000..971bfd01e0 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/ClearRecordedDataBottomSheetFragment.java @@ -0,0 +1,160 @@ +package net.osmand.plus.monitoring; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.widgets.TextViewEx; + +import androidx.annotation.DimenRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +public class ClearRecordedDataBottomSheetFragment extends MenuBottomSheetDialogFragment implements View.OnClickListener { + + public static final String TAG = ClearRecordedDataBottomSheetFragment.class.getSimpleName(); + + private OsmandApplication app; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(app.getString(R.string.clear_recorded_data_warning)) + .setDescriptionColorId(!nightMode ? R.color.text_color_primary_light : R.color.text_color_primary_dark) + .setDescriptionMaxLines(2) + .setTitle(app.getString(R.string.clear_recorded_data)) + .setLayoutId(R.layout.bottom_sheet_item_title_with_description) + .create()); + + LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupBtn(inflater, ButtonType.CLEAR)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupBtn(inflater, ButtonType.CANCEL)) + .setOnClickListener(this) + .create()); + + } + + private View setupBtn(LayoutInflater inflater, ButtonType type) { + View button = inflater.inflate(R.layout.bottom_sheet_item_button_with_icon, null); + button.setTag(type); + Context context = button.getContext(); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding); + int top = context.getResources().getDimensionPixelSize(type.topMarginRes); + int bottom = context.getResources().getDimensionPixelSize(R.dimen.content_padding_small); + params.setMargins(horizontal, top, horizontal, bottom); + button.setLayoutParams(params); + + UiUtilities.setupDialogButton(nightMode, button, type.effect, type.titleId); + + TextViewEx title = button.findViewById(R.id.button_text); + int margin = context.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + UiUtilities.setMargins(title, 0, margin, 0, margin); + + int colorRes; + if (type.effect == UiUtilities.DialogButtonType.SECONDARY_HARMFUL) { + colorRes = R.color.color_osm_edit_delete; + } else { + colorRes = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light; + } + AppCompatImageView icon = button.findViewById(R.id.icon); + icon.setImageDrawable(getIcon(type.iconRes, colorRes)); + + return button; + } + + @Override + public void onClick(View v) { + Object o = v.getTag(); + if (!(o instanceof ButtonType)) { + return; + } + + ButtonType tag = (ButtonType) o; + if (tag == ButtonType.CLEAR) { + app.getSavingTrackHelper().clearRecordedData(true); + } + dismiss(); + } + + @Override + public void onResume() { + super.onResume(); + // Replace later with tTripRecordingActiveBottomSheet.hide() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + } + + @Override + public void onPause() { + super.onPause(); + // Replace later with tTripRecordingActiveBottomSheet.show() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.show(); + } + } + } + + enum ButtonType { + CLEAR(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark, R.dimen.dialog_content_margin, UiUtilities.DialogButtonType.SECONDARY_HARMFUL), + CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close, R.dimen.content_padding_small, UiUtilities.DialogButtonType.SECONDARY); + + @StringRes + private final int titleId; + @DrawableRes + private final int iconRes; + @DimenRes + private final int topMarginRes; + private final UiUtilities.DialogButtonType effect; + + ButtonType(int titleId, int iconRes, int topMarginRes, UiUtilities.DialogButtonType effect) { + this.titleId = titleId; + this.iconRes = iconRes; + this.topMarginRes = topMarginRes; + this.effect = effect; + } + } + + @Override + protected boolean hideButtonsContainer() { + return true; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + if (!fragmentManager.isStateSaved()) { + ClearRecordedDataBottomSheetFragment fragment = new ClearRecordedDataBottomSheetFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java new file mode 100644 index 0000000000..b7bf829457 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/StopTrackRecordingBottomFragment.java @@ -0,0 +1,187 @@ +package net.osmand.plus.monitoring; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.widgets.TextViewEx; + +import androidx.annotation.DimenRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +public class StopTrackRecordingBottomFragment extends MenuBottomSheetDialogFragment implements View.OnClickListener { + + public static final String TAG = StopTrackRecordingBottomFragment.class.getSimpleName(); + + private OsmandApplication app; + private OsmandSettings settings; + private OsmandMonitoringPlugin plugin; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + settings = app.getSettings(); + plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class); + + items.add(new BottomSheetItemWithDescription.Builder() + .setDescription(app.getString(R.string.track_recording_description)) + .setDescriptionColorId(!nightMode ? R.color.text_color_primary_light : R.color.text_color_primary_dark) + .setDescriptionMaxLines(4) + .setTitle(app.getString(R.string.track_recording_title)) + .setLayoutId(R.layout.bottom_sheet_item_title_with_description) + .create()); + + LayoutInflater inflater = UiUtilities.getInflater(getContext(), nightMode); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.STOP_AND_DISCARD)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.SAVE_AND_STOP)) + .setOnClickListener(this) + .create()); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(setupButton(inflater, ButtonType.CANCEL)) + .setOnClickListener(this) + .create()); + } + + private View setupButton(LayoutInflater inflater, ButtonType type) { + View button = inflater.inflate(R.layout.bottom_sheet_item_button_with_icon, null); + button.setTag(type); + Context context = button.getContext(); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + int horizontal = context.getResources().getDimensionPixelSize(R.dimen.content_padding); + int top = context.getResources().getDimensionPixelSize(type.topMarginRes); + int bottom = context.getResources().getDimensionPixelSize(R.dimen.content_padding_small); + params.setMargins(horizontal, top, horizontal, bottom); + button.setLayoutParams(params); + + UiUtilities.setupDialogButton(nightMode, button, type.effect, type.titleId); + + TextViewEx title = button.findViewById(R.id.button_text); + int margin = context.getResources().getDimensionPixelSize(R.dimen.context_menu_padding_margin_medium); + UiUtilities.setMargins(title, 0, margin, 0, margin); + + int colorRes; + if (type.effect == DialogButtonType.SECONDARY_HARMFUL) { + colorRes = R.color.color_osm_edit_delete; + } else { + colorRes = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light; + } + AppCompatImageView icon = button.findViewById(R.id.icon); + icon.setImageDrawable(getIcon(type.iconRes, colorRes)); + + if (type == ButtonType.STOP_AND_DISCARD) { + int size = context.getResources().getDimensionPixelSize(R.dimen.map_widget_height); + LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(size, size); + icon.setLayoutParams(iconParams); + } + + return button; + } + + @Override + public void onClick(View v) { + Object o = v.getTag(); + if (!(o instanceof ButtonType)) { + return; + } + + ButtonType tag = (ButtonType) o; + if (tag == ButtonType.STOP_AND_DISCARD) { + if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { + plugin.stopRecording(); + app.getNotificationHelper().refreshNotifications(); + } + app.getSavingTrackHelper().clearRecordedData(true); + } else if (tag == ButtonType.SAVE_AND_STOP) { + if (plugin != null && settings.SAVE_GLOBAL_TRACK_TO_GPX.get()) { + plugin.saveCurrentTrack(); + app.getNotificationHelper().refreshNotifications(); + } + } + dismiss(); + } + + @Override + public void onResume() { + super.onResume(); + // Replace later with tTripRecordingActiveBottomSheet.hide() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + } + + @Override + public void onPause() { + super.onPause(); + // Replace later with tTripRecordingActiveBottomSheet.show() + Fragment target = getTargetFragment(); + if (target instanceof TripRecordingActiveBottomSheet) { + Dialog dialog = ((TripRecordingActiveBottomSheet) target).getDialog(); + if (dialog != null) { + dialog.show(); + } + } + } + + enum ButtonType { + STOP_AND_DISCARD(R.string.track_recording_stop_without_saving, R.drawable.ic_action_rec_stop, R.dimen.dialog_content_margin, DialogButtonType.SECONDARY_HARMFUL), + SAVE_AND_STOP(R.string.track_recording_save_and_stop, R.drawable.ic_action_save_to_file, R.dimen.content_padding_small, DialogButtonType.SECONDARY), + CANCEL(R.string.shared_string_cancel, R.drawable.ic_action_close, R.dimen.zero, DialogButtonType.SECONDARY); + + @StringRes + private final int titleId; + @DrawableRes + private final int iconRes; + @DimenRes + private final int topMarginRes; + private final DialogButtonType effect; + + ButtonType(int titleId, int iconRes, int topMarginRes, DialogButtonType type) { + this.titleId = titleId; + this.iconRes = iconRes; + this.topMarginRes = topMarginRes; + this.effect = type; + } + } + + @Override + protected boolean hideButtonsContainer() { + return true; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, @NonNull Fragment target) { + if (!fragmentManager.isStateSaved()) { + StopTrackRecordingBottomFragment fragment = new StopTrackRecordingBottomFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); + } + } +} From 3b0b49ae1b12b7b08613b173f4296f056110de02 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 8 Feb 2021 02:35:54 +0200 Subject: [PATCH 2/4] First part integration --- .../aidlapi/OsmAndCustomizationConstants.java | 1 + .../bottom_sheet_item_button_with_icon.xml | 3 +- OsmAnd/res/values/strings.xml | 2 +- .../plus/activities/MapActivityActions.java | 20 +++ .../monitoring/OsmandMonitoringPlugin.java | 13 +- .../TripRecordingActiveBottomSheet.java | 151 +++++++++++++----- 6 files changed, 144 insertions(+), 46 deletions(-) diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java index af48552bc4..53e838a9a7 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java @@ -11,6 +11,7 @@ public interface OsmAndCustomizationConstants { String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places"; String DRAWER_SEARCH_ID = DRAWER_ITEM_ID_SCHEME + "search"; String DRAWER_DIRECTIONS_ID = DRAWER_ITEM_ID_SCHEME + "directions"; + String DRAWER_TRIP_RECORDING_ID = DRAWER_ITEM_ID_SCHEME + "trip_recording"; String DRAWER_CONFIGURE_MAP_ID = DRAWER_ITEM_ID_SCHEME + "configure_map"; String DRAWER_DOWNLOAD_MAPS_ID = DRAWER_ITEM_ID_SCHEME + "download_maps"; String DRAWER_OSMAND_LIVE_ID = DRAWER_ITEM_ID_SCHEME + "osmand_live"; diff --git a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml index 9b2b395ccb..3d2d1bbab1 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_button_with_icon.xml @@ -34,7 +34,6 @@ android:layout_height="wrap_content" android:duplicateParentState="true" android:textSize="@dimen/default_desc_text_size" - osmand:letterSpacing="@dimen/description_letter_spacing" osmand:typeface="@string/font_roboto_medium" tools:text="Title" tools:textColor="@color/text_color_secondary_light" /> @@ -47,7 +46,7 @@ android:textColor="@color/text_color_secondary_light" android:textSize="@dimen/default_desc_text_size" android:visibility="gone" - osmand:letterSpacing="@dimen/description_letter_spacing" + android:letterSpacing="@dimen/description_letter_spacing" osmand:typeface="@string/font_roboto_medium" tools:text="Description" tools:visibility="visible" /> diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 905a947661..b2a92f75c2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,7 +11,7 @@ Thx - Hardy --> - + On pause Are you sure you want to stop recording?\nAll unsaved data will be lost. Track recording stopped Save and stop recording diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 258ed7be38..625396e5e3 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -22,6 +22,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; @@ -62,6 +63,8 @@ import net.osmand.plus.mapmarkers.MarkersPlanRouteContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.StartPlanRouteBottomSheet; import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.monitoring.TripRecordingActiveBottomSheet; +import net.osmand.plus.monitoring.TripRecordingBottomSheet; import net.osmand.plus.osmedit.dialogs.DismissRouteBottomSheetFragment; import net.osmand.plus.profiles.ProfileDataObject; import net.osmand.plus.profiles.ProfileDataUtils; @@ -98,6 +101,7 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_P import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_CONFIGURE_SCREEN_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DASHBOARD_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DIRECTIONS_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_TRIP_RECORDING_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DIVIDER_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_DOWNLOAD_MAPS_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_HELP_ID; @@ -839,6 +843,22 @@ public class MapActivityActions implements DialogProvider { } }).createItem()); + boolean isTripRecordingPluginOn = OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null; + if (isTripRecordingPluginOn) { + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.map_widget_monitoring, mapActivity) + .setId(DRAWER_TRIP_RECORDING_ID) + .setIcon(R.drawable.ic_action_track_recordable) + .setListener(new ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { + app.logEvent("trip_recording_open"); + MapActivity.clearPrevActivityIntent(); + TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); + return true; + } + }).createItem()); + } + optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.get_directions, mapActivity) .setId(DRAWER_DIRECTIONS_ID) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 1ddb443891..65538733b0 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -43,6 +43,7 @@ import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType; +import net.osmand.plus.track.TrackDisplayHelper; import net.osmand.plus.views.OsmandMapLayer.DrawSettings; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.layers.MapInfoLayer; @@ -318,9 +319,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public void controlDialog(final Activity activity, final boolean showTrackSelection) { - FragmentActivity fragmentActivity = (FragmentActivity) activity; - TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); - /*final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); + final boolean wasTrackMonitored = settings.SAVE_GLOBAL_TRACK_TO_GPX.get(); final boolean nightMode; if (activity instanceof MapActivity) { nightMode = app.getDaynightHelper().isNightModeForMapControls(); @@ -329,6 +328,8 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } AlertDialog.Builder bld = new AlertDialog.Builder(UiUtilities.getThemedContext(activity, nightMode)); final TIntArrayList items = new TIntArrayList(); + FragmentActivity fragmentActivity = (FragmentActivity) activity; + TripRecordingActiveBottomSheet.showInstance(fragmentActivity.getSupportFragmentManager()); if (wasTrackMonitored) { items.add(R.string.gpx_monitoring_stop); items.add(R.string.gpx_start_new_segment); @@ -417,7 +418,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { run.run(); } }); - bld.show(); +// bld.show(); } } @@ -538,7 +539,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } public static LinearLayout createIntervalChooseLayout(final OsmandApplication app, - final Context uiCtx, + final Context uiCtx, final String patternMsg, final int[] seconds, final int[] minutes, final ValueHolder choice, final ValueHolder v, @@ -598,7 +599,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } } - + ll.setOrientation(LinearLayout.VERTICAL); ll.addView(tv); ll.addView(sliderContainer); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 6234d58b18..3e3fad8b75 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -4,8 +4,10 @@ import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.graphics.drawable.Drawable; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -21,34 +23,84 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import com.google.android.material.snackbar.Snackbar; + +import net.osmand.GPXUtilities; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.TrackAppearanceFragment; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragment { public static final String TAG = TripRecordingActiveBottomSheet.class.getSimpleName(); - private OsmandApplication app; - private OsmandSettings settings; + SaveGpxAsyncTask.SaveGpxListener saveGpxListener = new SaveGpxAsyncTask.SaveGpxListener() { + + @Override + public void gpxSavingStarted() { + + } + + @Override + public void gpxSavingFinished(Exception errorMessage) { + String gpxFileName = Algorithms.getFileWithoutDirs(app.getSavingTrackHelper().getCurrentTrack().getGpxFile().path); + final MapActivity mapActivity = getMapActivity(); + SavingTrackHelper helper = app.getSavingTrackHelper(); + final SavingTrackHelper.SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); + if (mapActivity != null) { + Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), + getString(R.string.shared_string_file_is_saved, gpxFileName), + Snackbar.LENGTH_LONG) + .setAction(R.string.shared_string_undo, new View.OnClickListener() { + @Override + public void onClick(View view) { + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + final FragmentActivity fragmentActivity = mapActivityRef.get(); + SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); + } + }); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + dismiss(); + } + } + + }; + + public static void showInstance(@NonNull FragmentManager fragmentManager) { + if (!fragmentManager.isStateSaved()) { + TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); + fragment.show(fragmentManager, TAG); + } + } @Override public void createMenuItems(Bundle savedInstanceState) { app = requiredMyApplication(); - settings = app.getSettings(); + OsmandSettings settings = app.getSettings(); Context context = requireContext(); LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); @@ -67,6 +119,19 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen ); statusIcon.setImageDrawable(statusDrawable); + String timeTrackSaved = String.valueOf(app.getSavingTrackHelper().getLastTimeUpdated()); + SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + CharSequence formattedTimeTrackSaved = null; + try { + long time = sdf.parse(timeTrackSaved).getTime(); + long now = System.currentTimeMillis(); + formattedTimeTrackSaved = + DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); + } catch (ParseException e) { + e.printStackTrace(); + } + View buttonClear = itemView.findViewById(R.id.button_clear); View buttonStart = itemView.findViewById(R.id.button_start); View buttonSave = itemView.findViewById(R.id.button_save); @@ -75,7 +140,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen createButton(buttonClear, ItemType.CLEAR_DATA, true, null); createButton(buttonStart, ItemType.START_SEGMENT, true, null); - createButton(buttonSave, ItemType.SAVE, true, "17 min. ago"); + createButton(buttonSave, ItemType.SAVE, true, (String) formattedTimeTrackSaved); createButton(buttonPause, ItemType.PAUSE, true, null); createButton(buttonStop, ItemType.STOP, true, null); @@ -116,6 +181,25 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen }); UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + buttonSave.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final GPXUtilities.GPXFile gpxFile = app.getSavingTrackHelper().getCurrentTrack().getGpxFile(); + new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + } + }); + + buttonStop.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentManager fragmentManager = getFragmentManager(); + Fragment targetFragment = getTargetFragment(); + if (fragmentManager != null && targetFragment != null) { + StopTrackRecordingBottomFragment.showInstance(fragmentManager, targetFragment); + } + } + }); } private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { @@ -150,35 +234,6 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen desc.setText(description); } - enum ItemType { - SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), - RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), - ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), - CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), - START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), - SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), - PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), - STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); - - @StringRes - private int titleId; - @DrawableRes - private int iconId; - - ItemType(@StringRes int titleId, @DrawableRes int iconId) { - this.titleId = titleId; - this.iconId = iconId; - } - - public int getTitleId() { - return titleId; - } - - public int getIconId() { - return iconId; - } - } - @ColorRes protected int getActiveTextColorId() { return nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light; @@ -235,10 +290,32 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen } } - public static void showInstance(@NonNull FragmentManager fragmentManager) { - if (!fragmentManager.isStateSaved()) { - TripRecordingActiveBottomSheet fragment = new TripRecordingActiveBottomSheet(); - fragment.show(fragmentManager, TAG); + enum ItemType { + SEARCHING_GPS(R.string.searching_gps, R.drawable.ic_action_gps_info), + RECORDING(R.string.recording_default_name, R.drawable.ic_action_track_recordable), + ON_PAUSE(R.string.on_pause, R.drawable.ic_pause), + CLEAR_DATA(R.string.clear_recorded_data, R.drawable.ic_action_delete_dark), + START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), + SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), + PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); + + @StringRes + private int titleId; + @DrawableRes + private int iconId; + + ItemType(@StringRes int titleId, @DrawableRes int iconId) { + this.titleId = titleId; + this.iconId = iconId; + } + + public int getTitleId() { + return titleId; + } + + public int getIconId() { + return iconId; } } } From 38ab4a14fdb819a88e46609f51f7869cae206055 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 8 Feb 2021 12:39:29 +0200 Subject: [PATCH 3/4] Update TripRecordingActiveBottomSheet.java --- .../TripRecordingActiveBottomSheet.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index 3e3fad8b75..f085c581bd 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -49,6 +49,7 @@ import net.osmand.util.Algorithms; import java.lang.ref.WeakReference; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Date; import java.util.TimeZone; import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; @@ -102,6 +103,8 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen app = requiredMyApplication(); OsmandSettings settings = app.getSettings(); Context context = requireContext(); + final FragmentManager fragmentManager = getFragmentManager(); + final Fragment targetFragment = getTargetFragment(); LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); View itemView = inflater.inflate(R.layout.trip_recording_active_fragment, null, false); @@ -119,12 +122,14 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen ); statusIcon.setImageDrawable(statusDrawable); - String timeTrackSaved = String.valueOf(app.getSavingTrackHelper().getLastTimeUpdated()); - SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy HH:mm"); + long timeTrackSaved = app.getSavingTrackHelper().getLastTimeUpdated(); + SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z"); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + Date resultDate = new Date(timeTrackSaved); + String sdfFormatted = sdf.format(resultDate); CharSequence formattedTimeTrackSaved = null; try { - long time = sdf.parse(timeTrackSaved).getTime(); + long time = sdf.parse(sdfFormatted).getTime(); long now = System.currentTimeMillis(); formattedTimeTrackSaved = DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS); @@ -186,20 +191,26 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void onClick(View v) { final GPXUtilities.GPXFile gpxFile = app.getSavingTrackHelper().getCurrentTrack().getGpxFile(); new SaveCurrentTrackTask(app, gpxFile, saveGpxListener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } }); buttonStop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - FragmentManager fragmentManager = getFragmentManager(); - Fragment targetFragment = getTargetFragment(); - if (fragmentManager != null && targetFragment != null) { + if (fragmentManager != null) { StopTrackRecordingBottomFragment.showInstance(fragmentManager, targetFragment); } } }); + + buttonClear.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fragmentManager != null) { + ClearRecordedDataBottomSheetFragment.showInstance(fragmentManager, targetFragment); + } + } + }); } private void createButton(View view, ItemType type, boolean enabled, @Nullable String description) { From b79e4bd9964e4515c19ac15f43702bf12117814e Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:08:30 +0200 Subject: [PATCH 4/4] Snackbar top --- .../monitoring/TripRecordingActiveBottomSheet.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java index f085c581bd..8c37b6903e 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingActiveBottomSheet.java @@ -8,8 +8,10 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.text.format.DateUtils; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -29,6 +31,7 @@ import androidx.fragment.app.FragmentManager; import com.google.android.material.snackbar.Snackbar; +import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.OsmandApplication; @@ -69,9 +72,10 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen public void gpxSavingFinished(Exception errorMessage) { String gpxFileName = Algorithms.getFileWithoutDirs(app.getSavingTrackHelper().getCurrentTrack().getGpxFile().path); final MapActivity mapActivity = getMapActivity(); + final Context context = getContext(); SavingTrackHelper helper = app.getSavingTrackHelper(); final SavingTrackHelper.SaveGpxResult result = helper.saveDataToGpx(app.getAppCustomization().getTracksDir()); - if (mapActivity != null) { + if (mapActivity != null && context != null) { Snackbar snackbar = Snackbar.make(mapActivity.getLayout(), getString(R.string.shared_string_file_is_saved, gpxFileName), Snackbar.LENGTH_LONG) @@ -83,9 +87,13 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen SaveGPXBottomSheetFragment.showInstance(fragmentActivity.getSupportFragmentManager(), result.getFilenames()); } }); + View view = snackbar.getView(); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); + params.gravity = Gravity.TOP; + AndroidUtils.setMargins(params, 0, AndroidUtils.getStatusBarHeight(context), 0, 0); + view.setLayoutParams(params); UiUtilities.setupSnackbar(snackbar, nightMode); snackbar.show(); - dismiss(); } } @@ -309,6 +317,7 @@ public class TripRecordingActiveBottomSheet extends MenuBottomSheetDialogFragmen START_SEGMENT(R.string.gpx_start_new_segment, R.drawable.ic_action_new_segment), SAVE(R.string.shared_string_save, R.drawable.ic_action_save_to_file), PAUSE(R.string.shared_string_pause, R.drawable.ic_pause), + RESUME(R.string.shared_string_pause, R.drawable.ic_play_dark), STOP(R.string.shared_string_control_stop, R.drawable.ic_action_rec_stop); @StringRes