From a5594a240f801ebfabddca2315a0f621a8177d85 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 12 Jan 2021 21:04:31 +0200 Subject: [PATCH 01/31] Fix open on map --- .../plus/wikivoyage/WikivoyageWebViewClient.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java index c2c42551e2..9433d6c854 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java @@ -12,8 +12,10 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; +import com.jwetherell.openmap.common.MoreMath; + import net.osmand.AndroidUtils; -import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; @@ -29,6 +31,7 @@ import net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity; import java.io.File; import java.util.List; +import static com.jwetherell.openmap.common.LatLonPoint.EQUIVALENT_TOLERANCE; import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKIVOYAGE_DOMAIN; import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKI_DOMAIN; @@ -91,15 +94,15 @@ public class WikivoyageWebViewClient extends WebViewClient { double lat; double lon; try { - lat = Double.valueOf(coordinates.substring(0, coordinates.indexOf(","))); - lon = Double.valueOf(coordinates.substring(coordinates.indexOf(",") + 1, - coordinates.length())); + lat = Double.parseDouble(coordinates.substring(0, coordinates.indexOf(","))); + lon = Double.parseDouble(coordinates.substring(coordinates.indexOf(",") + 1)); } catch (NumberFormatException e) { Log.w(TAG, e.getMessage(), e); return true; } for (WptPt point : points) { - if (point.getLatitude() == lat && point.getLongitude() == lon) { + if (MoreMath.approximately_equal(point.getLatitude(), lat, EQUIVALENT_TOLERANCE * 2) + && MoreMath.approximately_equal(point.getLongitude(), lon, EQUIVALENT_TOLERANCE * 2)) { gpxPoint = point; break; } From 469e2e6ee7b0d672cfcba1f0e19fa6e39055881f Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 13 Jan 2021 10:18:41 +0200 Subject: [PATCH 02/31] Fix open on map --- .../src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java index 9433d6c854..f9f3016725 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java @@ -122,7 +122,7 @@ public class WikivoyageWebViewClient extends WebViewClient { fragmentManager.popBackStackImmediate(); File path = app.getTravelHelper().createGpxFile(article); - GPXUtilities.GPXFile gpxFile = article.getGpxFile(); + GPXFile gpxFile = article.getGpxFile(); gpxFile.path = path.getAbsolutePath(); app.getSelectedGpxHelper().setGpxFileToDisplay(gpxFile); MapActivity.launchMapActivityMoveToTop(activity); From b4264077c47af4c8beb2b1493b7c09be6b46a129 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Wed, 13 Jan 2021 10:34:50 +0200 Subject: [PATCH 03/31] Fix open on map npe --- .../src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java index f9f3016725..beafb51ec4 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java @@ -87,7 +87,7 @@ public class WikivoyageWebViewClient extends WebViewClient { } else if (isWebPage) { WikiArticleHelper.warnAboutExternalLoad(url, activity, nightMode); } else if (url.startsWith(PREFIX_GEO)) { - if (article != null) { + if (article != null && article.getGpxFile() != null) { List points = article.getGpxFile().getPoints(); WptPt gpxPoint = null; String coordinates = url.replace(PREFIX_GEO, ""); From 847f99fbd52be54f6dc4d6579aeafeb2bedc8758 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 13 Jan 2021 16:07:28 +0200 Subject: [PATCH 04/31] "URL with all parameters will ..." is now above url --- .../osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 59df4ef698..e6ca05991b 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -284,7 +284,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return false; } }); - exampleCard.setFieldBoxHelperText(getString(R.string.online_routing_example_hint)); + exampleCard.setFieldBoxLabelText(getString(R.string.online_routing_example_hint)); exampleCard.setButton(getString(R.string.test_route_calculation), new View.OnClickListener() { @Override public void onClick(View v) { From 5a8a39ecf51bc8e93f70b385b296e0b8af051e1f Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 13 Jan 2021 16:59:50 +0200 Subject: [PATCH 05/31] fix previous; "Vehicle" block, descrease padding below scroll buttons --- .../net/osmand/plus/onlinerouting/OnlineRoutingCard.java | 6 ++++++ .../plus/onlinerouting/OnlineRoutingEngineFragment.java | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index 1b9e7f3b29..6c49386c47 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -5,6 +5,7 @@ import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; +import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; @@ -127,6 +128,11 @@ public class OnlineRoutingCard extends BaseCard { rvSelectionMenu.setAdapter(adapter); } + public void removeBottomMarginSelectionMenu() { + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); + params.bottomMargin = 0; + } + public void setDescription(@NonNull String description) { showElements(tvDescription); tvDescription.setText(description); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index e6ca05991b..b70fcc89a3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -230,6 +230,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return false; } }); + vehicleCard.removeBottomMarginSelectionMenu(); vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { @Override @@ -284,7 +285,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return false; } }); - exampleCard.setFieldBoxLabelText(getString(R.string.online_routing_example_hint)); + exampleCard.setDescription(getString(R.string.online_routing_example_hint)); + exampleCard.showFieldBox(); exampleCard.setButton(getString(R.string.test_route_calculation), new View.OnClickListener() { @Override public void onClick(View v) { From 4c4a439adcba078ca445fefc12a32ccddd0801a2 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 14 Jan 2021 12:30:49 +0200 Subject: [PATCH 06/31] Close keyboard on scrolling --- .../OnlineRoutingEngineFragment.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index b70fcc89a3..541803dbfd 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -7,6 +7,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -61,12 +62,14 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private View view; private ViewGroup segmentsContainer; + private ViewGroup scrollView; private OnlineRoutingCard nameCard; private OnlineRoutingCard typeCard; private OnlineRoutingCard vehicleCard; private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard exampleCard; private View testResultsContainer; + private ViewTreeObserver.OnScrollChangedListener onScroll; private ApplicationMode appMode; @@ -137,6 +140,20 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { view = getInflater().inflate( R.layout.online_routing_engine_fragment, container, false); segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); + scrollView = (ViewGroup) segmentsContainer.getParent(); + onScroll = new ViewTreeObserver.OnScrollChangedListener() { + int pastY = 0; + @Override + public void onScrollChanged() { + int y = scrollView.getScrollY(); + if (pastY != y) { + pastY = y; + View vieww = view.findFocus(); + AndroidUtils.hideSoftKeyboard(requireActivity(), vieww); + } + } + }; + scrollView.getViewTreeObserver().addOnScrollChangedListener(onScroll); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); } @@ -156,6 +173,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return view; } + @Override + public void onDestroyView() { + super.onDestroyView(); + scrollView.getViewTreeObserver().removeOnScrollChangedListener(onScroll); + } + private void setupNameCard() { nameCard = new OnlineRoutingCard(mapActivity, isNightMode()); nameCard.build(mapActivity); From ebbcb1778ff82127123f4409741ba4477a2cba03 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 14 Jan 2021 13:13:55 +0200 Subject: [PATCH 07/31] fix descrease padding below scroll buttons in "Vehicle" block --- .../net/osmand/plus/onlinerouting/OnlineRoutingCard.java | 4 ++-- .../plus/onlinerouting/OnlineRoutingEngineFragment.java | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index 6c49386c47..b9509fc026 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -128,9 +128,9 @@ public class OnlineRoutingCard extends BaseCard { rvSelectionMenu.setAdapter(adapter); } - public void removeBottomMarginSelectionMenu() { + public void updateBottomMarginSelectionMenu(int bottomMargin) { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); - params.bottomMargin = 0; + params.bottomMargin = bottomMargin; } public void setDescription(@NonNull String description) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 541803dbfd..457fc2ee17 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -248,12 +248,17 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (engine.vehicleType != vehicle) { engine.vehicleType = vehicle; updateCardViews(nameCard, vehicleCard, exampleCard); + if (vehicle == VehicleType.CUSTOM) { + vehicleCard.updateBottomMarginSelectionMenu((int) getResources().getDimension(R.dimen.content_padding)); + } else { + vehicleCard.updateBottomMarginSelectionMenu(0); + } return true; } return false; } }); - vehicleCard.removeBottomMarginSelectionMenu(); + vehicleCard.updateBottomMarginSelectionMenu(0); vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { @Override From d75134129d4d38c0951a2e7ac558b668b1c3df49 Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 14 Jan 2021 18:14:45 +0200 Subject: [PATCH 08/31] Textfields, use profile color as active color; Dismiss bottom sheet --- .../plus/onlinerouting/OnlineRoutingCard.java | 4 + .../OnlineRoutingEngineFragment.java | 80 +++++++++++++++++-- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index b9509fc026..0ac677a4ae 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -68,6 +68,10 @@ public class OnlineRoutingCard extends BaseCard { bottomDivider = view.findViewById(R.id.bottom_divider); button = view.findViewById(R.id.button); + textFieldBoxes.setPrimaryColor(nightMode + ? view.getContext().getResources().getColor(R.color.active_color_primary_dark) + : view.getContext().getResources().getColor(R.color.active_color_primary_light)); + editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 457fc2ee17..c34d6541a1 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -1,6 +1,8 @@ package net.osmand.plus.onlinerouting; +import android.app.Activity; import android.content.Context; +import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; @@ -12,8 +14,10 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -74,6 +78,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private ApplicationMode appMode; private OnlineRoutingEngineObject engine; + private OnlineRoutingEngineObject initEngine; private ExampleLocation selectedLocation; private String editedEngineKey; @@ -125,11 +130,20 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { mapActivity = getMapActivity(); helper = app.getOnlineRoutingHelper(); engine = new OnlineRoutingEngineObject(); + initEngine = new OnlineRoutingEngineObject(); if (savedInstanceState != null) { restoreState(savedInstanceState); } else { initState(); } + requireMyActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + public void handleOnBackPressed() { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + showExitDialog(); + } + } + }); } @Nullable @@ -143,13 +157,14 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { scrollView = (ViewGroup) segmentsContainer.getParent(); onScroll = new ViewTreeObserver.OnScrollChangedListener() { int pastY = 0; + @Override public void onScrollChanged() { int y = scrollView.getScrollY(); if (pastY != y) { pastY = y; - View vieww = view.findFocus(); - AndroidUtils.hideSoftKeyboard(requireActivity(), vieww); + View focus = view.findFocus(); + AndroidUtils.hideSoftKeyboard(requireActivity(), focus); } } }; @@ -166,6 +181,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupExampleCard(); setupResultsContainer(); addSpaceSegment(); + engine.cloneIn(initEngine); setupButtons(); @@ -345,7 +361,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { navigationIcon.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - dismiss(); + showExitDialog(); } }); TextView title = toolbar.findViewById(R.id.toolbar_title); @@ -415,7 +431,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - dismiss(); + showExitDialog(); } }); @@ -571,10 +587,41 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void dismiss() { FragmentActivity activity = getActivity(); if (activity != null) { - activity.onBackPressed(); + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + if (!fragmentManager.isStateSaved()) { + fragmentManager.popBackStack(); + } } } + public void showExitDialog() { + View focus = view.findFocus(); + AndroidUtils.hideSoftKeyboard(requireMyActivity(), focus); + + if (!engine.equals(initEngine)) { + AlertDialog.Builder dismissDialog = createWarningDialog(getActivity(), + R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel); + dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dismiss(); + } + }); + dismissDialog.show(); + } else { + dismiss(); + } + } + + private AlertDialog.Builder createWarningDialog(Activity activity, int title, int message, int negButton) { + Context themedContext = UiUtilities.getThemedContext(activity, isNightMode()); + AlertDialog.Builder warningDialog = new AlertDialog.Builder(themedContext); + warningDialog.setTitle(getString(title)); + warningDialog.setMessage(getString(message)); + warningDialog.setNegativeButton(negButton, null); + return warningDialog; + } + private boolean isNightMode() { return !app.getSettings().isLightContentForMode(appMode); } @@ -635,5 +682,28 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } return customServerUrl; } + + public void cloneIn(OnlineRoutingEngineObject clone) { + clone.customName = customName; + clone.type = type; + clone.customServerUrl = customServerUrl; + clone.vehicleType = vehicleType; + clone.customVehicleKey = customVehicleKey; + clone.apiKey = apiKey; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + OnlineRoutingEngineObject engine = (OnlineRoutingEngineObject) obj; + if (customName != engine.customName) return false; + if (type != engine.type) return false; + if (customServerUrl != engine.customServerUrl) return false; + if (vehicleType != engine.vehicleType) return false; + if (customVehicleKey != engine.customVehicleKey) return false; + return apiKey == engine.apiKey; + } } } From 839507832945bf9e9239d7137a0ff04d335c68c3 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Fri, 15 Jan 2021 17:45:29 +0200 Subject: [PATCH 09/31] Implement Online routing backend p.2 --- .../bottom_sheet_item_with_descr_64dp.xml | 3 +- .../online_routing_preference_segment.xml | 13 + OsmAnd/res/values/strings.xml | 16 +- .../plus/onlinerouting/EngineParameter.java | 10 + .../osmand/plus/onlinerouting/EngineType.java | 24 - .../onlinerouting/OnlineRoutingEngine.java | 109 ---- .../onlinerouting/OnlineRoutingFactory.java | 36 ++ .../onlinerouting/OnlineRoutingHelper.java | 214 +++---- .../plus/onlinerouting/VehicleType.java | 44 +- .../plus/onlinerouting/engine/EngineType.java | 34 + .../engine/GraphhopperEngine.java | 93 +++ .../engine/OnlineRoutingEngine.java | 197 ++++++ .../plus/onlinerouting/engine/OrsEngine.java | 102 +++ .../plus/onlinerouting/engine/OsrmEngine.java | 82 +++ .../onlinerouting/ui/ExampleLocation.java | 52 ++ .../{ => ui}/OnlineRoutingCard.java | 39 +- .../{ => ui}/OnlineRoutingEngineFragment.java | 595 +++++++++--------- .../OnlineRoutingEngineDataObject.java | 17 +- .../plus/profiles/ProfileDataUtils.java | 25 +- .../profiles/SelectProfileBottomSheet.java | 5 +- .../osmand/plus/routing/RouteProvider.java | 18 +- .../backup/OnlineRoutingSettingsItem.java | 9 +- .../backend/backup/SettingsHelper.java | 2 +- .../fragments/DuplicatesSettingsAdapter.java | 2 +- .../fragments/ExportItemsBottomSheet.java | 2 +- .../fragments/ImportDuplicatesFragment.java | 2 +- .../fragments/ImportSettingsFragment.java | 2 +- .../fragments/NavigationFragment.java | 2 +- 28 files changed, 1107 insertions(+), 642 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/EngineParameter.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java delete mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java create mode 100644 OsmAnd/src/net/osmand/plus/onlinerouting/ui/ExampleLocation.java rename OsmAnd/src/net/osmand/plus/onlinerouting/{ => ui}/OnlineRoutingCard.java (81%) rename OsmAnd/src/net/osmand/plus/onlinerouting/{ => ui}/OnlineRoutingEngineFragment.java (57%) diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml index 2ff6a1bf58..95091e1086 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_64dp.xml @@ -27,6 +27,8 @@ android:layout_weight="1" android:layout_marginLeft="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding" + android:paddingTop="@dimen/content_padding_small" + android:paddingBottom="@dimen/content_padding_small" android:orientation="vertical"> + + - + The name is already exists + Server error: %1$s + MTB + Racing bike + Scooter + Truck + Small truck + HGV + Regular cycling + Road cycling + Mountain cycling + Electric cycling + Walking + Hiking + Wheelchair Empty Select folder or add new one Select folder diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineParameter.java b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineParameter.java new file mode 100644 index 0000000000..fa3ccd81c7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineParameter.java @@ -0,0 +1,10 @@ +package net.osmand.plus.onlinerouting; + +public enum EngineParameter { + KEY, + VEHICLE_KEY, + CUSTOM_NAME, + NAME_INDEX, + CUSTOM_URL, + API_KEY +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java deleted file mode 100644 index fe5080f14c..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/EngineType.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.osmand.plus.onlinerouting; - -public enum EngineType { - - GRAPHHOPPER("Graphhopper", "https://graphhopper.com/api/1/route"), - OSRM("OSRM", "https://router.project-osrm.org/route/v1/"), - ORS("Openroute Service", "https://api.openrouteservice.org/v2/directions/"); - - private String title; - private String standardUrl; - - EngineType(String title, String standardUrl) { - this.title = title; - this.standardUrl = standardUrl; - } - - public String getTitle() { - return title; - } - - public String getStandardUrl() { - return standardUrl; - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java deleted file mode 100644 index 3193d86d09..0000000000 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngine.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.osmand.plus.onlinerouting; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.osmand.plus.R; -import net.osmand.util.Algorithms; - -import java.util.HashMap; -import java.util.Map; - -public class OnlineRoutingEngine { - - public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; - - public enum EngineParameter { - CUSTOM_NAME, - CUSTOM_URL, - API_KEY - } - - private String stringKey; - private EngineType type; - private String vehicleKey; - private Map params = new HashMap<>(); - - public OnlineRoutingEngine(@NonNull String stringKey, - @NonNull EngineType type, - @NonNull String vehicleKey, - @Nullable Map params) { - this(stringKey, type, vehicleKey); - if (!Algorithms.isEmpty(params)) { - this.params.putAll(params); - } - } - - public OnlineRoutingEngine(@NonNull String stringKey, - @NonNull EngineType type, - @NonNull String vehicleKey) { - this.stringKey = stringKey; - this.type = type; - this.vehicleKey = vehicleKey; - } - - public String getStringKey() { - return stringKey; - } - - public EngineType getType() { - return type; - } - - public String getBaseUrl() { - String customUrl = getParameter(EngineParameter.CUSTOM_URL); - if (Algorithms.isEmpty(customUrl)) { - return type.getStandardUrl(); - } - return customUrl; - } - - public String getVehicleKey() { - return vehicleKey; - } - - public Map getParams() { - return params; - } - - public String getParameter(EngineParameter paramKey) { - return params.get(paramKey.name()); - } - - public void putParameter(EngineParameter paramKey, String paramValue) { - params.put(paramKey.name(), paramValue); - } - - public String getName(@NonNull Context ctx) { - String customName = getParameter(EngineParameter.CUSTOM_NAME); - if (customName != null) { - return customName; - } else { - return getStandardName(ctx); - } - } - - private String getStandardName(@NonNull Context ctx) { - return getStandardName(ctx, type, vehicleKey); - } - - public static String getStandardName(@NonNull Context ctx, - @NonNull EngineType type, - @NonNull String vehicleKey) { - String vehicleTitle = VehicleType.toHumanString(ctx, vehicleKey); - String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash); - return String.format(pattern, type.getTitle(), vehicleTitle); - } - - public static OnlineRoutingEngine createNewEngine(@NonNull EngineType type, - @NonNull String vehicleKey, - @Nullable Map params) { - return new OnlineRoutingEngine(generateKey(), type, vehicleKey, params); - } - - private static String generateKey() { - return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); - } -} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java new file mode 100644 index 0000000000..4b92000847 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingFactory.java @@ -0,0 +1,36 @@ +package net.osmand.plus.onlinerouting; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.plus.onlinerouting.engine.EngineType; +import net.osmand.plus.onlinerouting.engine.GraphhopperEngine; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.engine.OrsEngine; +import net.osmand.plus.onlinerouting.engine.OsrmEngine; + +import java.util.Map; + +public class OnlineRoutingFactory { + + public static OnlineRoutingEngine createEngine(@NonNull EngineType type) { + return createEngine(type, null); + } + + @NonNull + public static OnlineRoutingEngine createEngine(@NonNull EngineType type, + @Nullable Map params) { + switch (type) { + case GRAPHHOPPER: + return new GraphhopperEngine(params); + case OSRM: + return new OsrmEngine(params); + case ORS: + return new OrsEngine(params); + default: + throw new IllegalArgumentException( + "Online routing type {" + type.name() + "} not supported"); + } + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index b54746ddd6..bf4f41a096 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -1,6 +1,7 @@ package net.osmand.plus.onlinerouting; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -10,10 +11,10 @@ import net.osmand.data.LatLon; import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.Version; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; +import net.osmand.plus.onlinerouting.engine.EngineType; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; -import net.osmand.util.GeoPolylineParserUtil; import org.apache.commons.logging.Log; import org.json.JSONArray; @@ -24,7 +25,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Type; -import java.net.URLConnection; +import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -35,14 +36,18 @@ public class OnlineRoutingHelper { private static final Log LOG = PlatformUtil.getLog(OnlineRoutingHelper.class); + private static final String ITEMS = "items"; + private static final String TYPE = "type"; + private static final String PARAMS = "params"; + private OsmandApplication app; private OsmandSettings settings; private Map cachedEngines; - public OnlineRoutingHelper(OsmandApplication app) { + public OnlineRoutingHelper(@NonNull OsmandApplication app) { this.app = app; this.settings = app.getSettings(); - loadFromSettings(); + this.cachedEngines = loadSavedEngines(); } @NonNull @@ -50,104 +55,42 @@ public class OnlineRoutingHelper { return new ArrayList<>(cachedEngines.values()); } - public OnlineRoutingEngine getEngineByKey(String stringKey) { + @NonNull + public List getEnginesExceptMentioned(@Nullable String ... excludeKeys) { + List engines = getEngines(); + if (excludeKeys != null) { + for (String key : excludeKeys) { + OnlineRoutingEngine engine = getEngineByKey(key); + engines.remove(engine); + } + } + return engines; + } + + @Nullable + public OnlineRoutingEngine getEngineByKey(@Nullable String stringKey) { return cachedEngines.get(stringKey); } + @NonNull public List calculateRouteOnline(@NonNull OnlineRoutingEngine engine, @NonNull List path) throws IOException, JSONException { - String fullUrl = createFullUrl(engine, path); - String content = makeRequest(fullUrl); - return parseResponse(engine, content); + String url = engine.getFullUrl(path); + String content = makeRequest(url); + return engine.parseServerResponse(content); } - public String createFullUrl(OnlineRoutingEngine engine, List path) { - StringBuilder sb = new StringBuilder(engine.getBaseUrl()); - String vehicle = engine.getVehicleKey(); - String apiKey = engine.getParameter(EngineParameter.API_KEY); - switch (engine.getType()) { - - case GRAPHHOPPER: - sb.append("?"); - for (LatLon point : path) { - sb.append("point=") - .append(point.getLatitude()) - .append(',') - .append(point.getLongitude()) - .append('&'); - } - sb.append("vehicle=").append(vehicle); - - if (!Algorithms.isEmpty(apiKey)) { - sb.append('&').append("key=").append(apiKey); - } - break; - - case OSRM: - sb.append(vehicle).append('/'); - for (int i = 0; i < path.size(); i++) { - LatLon point = path.get(i); - sb.append(point.getLongitude()).append(',').append(point.getLatitude()); - if (i < path.size() - 1) { - sb.append(';'); - } - } - break; - - case ORS: - if (path.size() > 1) { - sb.append("driving-car").append('?'); // todo only for testing - if (!Algorithms.isEmpty(apiKey)) { - sb.append("api_key=").append(apiKey); - } - LatLon start = path.get(0); - LatLon end = path.get(path.size() - 1); - sb.append('&').append("start=") - .append(start.getLatitude()).append(',').append(start.getLongitude()); - sb.append('&').append("end=") - .append(end.getLatitude()).append(',').append(end.getLongitude()); - } - break; - - } - return sb.toString(); - } - - private List parseResponse(OnlineRoutingEngine engine, String content) throws JSONException { - JSONObject obj = new JSONObject(content); - - switch (engine.getType()) { - - case GRAPHHOPPER: - return GeoPolylineParserUtil.parse( - obj.getJSONArray("paths").getJSONObject(0).getString("points"), - GeoPolylineParserUtil.PRECISION_5); - - case OSRM: - return GeoPolylineParserUtil.parse( - obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), - GeoPolylineParserUtil.PRECISION_5); - - case ORS: - JSONArray array = obj.getJSONArray("features").getJSONObject(0) - .getJSONObject("geometry").getJSONArray("coordinates"); - List track = new ArrayList<>(); - for (int i = 0; i < array.length(); i++) { - JSONArray point = array.getJSONArray(i); - double lat = Double.parseDouble(point.getString(0)); - double lon = Double.parseDouble(point.getString(1)); - track.add(new LatLon(lat, lon)); - } - return track; - } - return new ArrayList<>(); - } - - private String makeRequest(String url) throws IOException { - URLConnection connection = NetworkUtils.getHttpURLConnection(url); + @NonNull + public String makeRequest(@NonNull String url) throws IOException { + HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url); connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); StringBuilder content = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + BufferedReader reader; + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + } else { + reader = new BufferedReader(new InputStreamReader(connection.getErrorStream())); + } String s; while ((s = reader.readLine()) != null) { content.append(s); @@ -160,32 +103,49 @@ public class OnlineRoutingHelper { } public void saveEngine(@NonNull OnlineRoutingEngine engine) { - String stringKey = engine.getStringKey(); - cachedEngines.put(stringKey, engine); - saveToSettings(); - } - - public void deleteEngine(@NonNull String stringKey) { - OnlineRoutingEngine engine = getEngineByKey(stringKey); - if (engine != null) { - deleteEngine(engine); - } + deleteInaccessibleParameters(engine); + String key = createEngineKeyIfNeeded(engine); + cachedEngines.put(key, engine); + saveCacheToSettings(); } public void deleteEngine(@NonNull OnlineRoutingEngine engine) { String stringKey = engine.getStringKey(); - if (cachedEngines.containsKey(stringKey)) { + deleteEngine(stringKey); + } + + public void deleteEngine(@Nullable String stringKey) { + if (stringKey != null) { cachedEngines.remove(stringKey); - saveToSettings(); + saveCacheToSettings(); } } - private void loadFromSettings() { + private void deleteInaccessibleParameters(@NonNull OnlineRoutingEngine engine) { + for (EngineParameter key : EngineParameter.values()) { + if (!engine.isParameterAllowed(key)) { + engine.remove(key); + } + } + } + + @NonNull + private String createEngineKeyIfNeeded(@NonNull OnlineRoutingEngine engine) { + String key = engine.get(EngineParameter.KEY); + if (Algorithms.isEmpty(key)) { + key = OnlineRoutingEngine.generateKey(); + engine.put(EngineParameter.KEY, key); + } + return key; + } + + @NonNull + private Map loadSavedEngines() { Map cachedEngines = new LinkedHashMap<>(); for (OnlineRoutingEngine engine : readFromSettings()) { cachedEngines.put(engine.getStringKey(), engine); } - this.cachedEngines = cachedEngines; + return cachedEngines; } @NonNull @@ -203,7 +163,7 @@ public class OnlineRoutingHelper { return engines; } - private void saveToSettings() { + private void saveCacheToSettings() { if (!Algorithms.isEmpty(cachedEngines)) { try { JSONObject json = new JSONObject(); @@ -217,38 +177,44 @@ public class OnlineRoutingHelper { } } - public static void readFromJson(JSONObject json, List engines) throws JSONException { + public static void readFromJson(@NonNull JSONObject json, + @NonNull List engines) throws JSONException { if (!json.has("items")) { return; } Gson gson = new Gson(); - Type type = new TypeToken>() { + Type typeToken = new TypeToken>() { }.getType(); - JSONArray itemsJson = json.getJSONArray("items"); + JSONArray itemsJson = json.getJSONArray(ITEMS); for (int i = 0; i < itemsJson.length(); i++) { JSONObject object = itemsJson.getJSONObject(i); - String key = object.getString("key"); - String vehicleKey = object.getString("vehicle"); - EngineType engineType = EngineType.valueOf(object.getString("type")); - String paramsString = object.getString("params"); - HashMap params = gson.fromJson(paramsString, type); - engines.add(new OnlineRoutingEngine(key, engineType, vehicleKey, params)); + if (object.has(TYPE) && object.has(PARAMS)) { + EngineType type = EngineType.getTypeByName(object.getString(TYPE)); + String paramsString = object.getString(PARAMS); + HashMap params = gson.fromJson(paramsString, typeToken); + OnlineRoutingEngine engine = OnlineRoutingFactory.createEngine(type, params); + if (!Algorithms.isEmpty(engine.getStringKey())) { + engines.add(engine); + } + } } } - public static void writeToJson(JSONObject json, List engines) throws JSONException { + public static void writeToJson(@NonNull JSONObject json, + @NonNull List engines) throws JSONException { JSONArray jsonArray = new JSONArray(); Gson gson = new Gson(); Type type = new TypeToken>() { }.getType(); for (OnlineRoutingEngine engine : engines) { + if (Algorithms.isEmpty(engine.getStringKey())) { + continue; + } JSONObject jsonObject = new JSONObject(); - jsonObject.put("key", engine.getStringKey()); - jsonObject.put("type", engine.getType().name()); - jsonObject.put("vehicle", engine.getVehicleKey()); - jsonObject.put("params", gson.toJson(engine.getParams(), type)); + jsonObject.put(TYPE, engine.getType().name()); + jsonObject.put(PARAMS, gson.toJson(engine.getParams(), type)); jsonArray.put(jsonObject); } - json.put("items", jsonArray); + json.put(ITEMS, jsonArray); } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java index 3e3fea6660..9936f8efbf 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/VehicleType.java @@ -3,48 +3,26 @@ package net.osmand.plus.onlinerouting; import android.content.Context; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; -import net.osmand.plus.R; -import net.osmand.util.Algorithms; +public class VehicleType { + private final String key; + @StringRes + private final int titleId; -public enum VehicleType { - CAR("car", R.string.routing_engine_vehicle_type_car), - BIKE("bike", R.string.routing_engine_vehicle_type_bike), - FOOT("foot", R.string.routing_engine_vehicle_type_foot), - DRIVING("driving", R.string.routing_engine_vehicle_type_driving), - CUSTOM("", R.string.shared_string_custom); - - VehicleType(String key, int titleId) { + public VehicleType(@NonNull String key, + @StringRes int titleId) { this.key = key; this.titleId = titleId; } - private String key; - private int titleId; - + @NonNull public String getKey() { return key; } - public String getTitle(Context ctx) { + @NonNull + public String getTitle(@NonNull Context ctx) { return ctx.getString(titleId); } - - public static String toHumanString(@NonNull Context ctx, - @NonNull String key) { - VehicleType vehicleType = getVehicleByKey(key); - if (vehicleType == CUSTOM) { - return Algorithms.capitalizeFirstLetter(key); - } - return vehicleType.getTitle(ctx); - } - - public static VehicleType getVehicleByKey(String key) { - for (VehicleType v : values()) { - if (Algorithms.objectEquals(v.getKey(), key)) { - return v; - } - } - return CUSTOM; - } -} \ No newline at end of file +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java new file mode 100644 index 0000000000..431ad33a3d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/EngineType.java @@ -0,0 +1,34 @@ +package net.osmand.plus.onlinerouting.engine; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.util.Algorithms; + +public enum EngineType { + GRAPHHOPPER("Graphhopper"), + OSRM("OSRM"), + ORS("Openroute Service"); + + private final String title; + + EngineType(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + @NonNull + public static EngineType getTypeByName(@Nullable String name) { + if (!Algorithms.isEmpty(name)) { + for (EngineType type : values()) { + if (type.name().equals(name)) { + return type; + } + } + } + return values()[0]; + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java new file mode 100644 index 0000000000..c7a31fb10c --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -0,0 +1,93 @@ +package net.osmand.plus.onlinerouting.engine; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.data.LatLon; +import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.util.GeoPolylineParserUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; + +public class GraphhopperEngine extends OnlineRoutingEngine { + + public GraphhopperEngine(@Nullable Map params) { + super(params); + } + + @Override + public @NonNull EngineType getType() { + return EngineType.GRAPHHOPPER; + } + + @NonNull + @Override + public String getStandardUrl() { + return "https://graphhopper.com/api/1/route"; + } + + @Override + protected void collectAllowedParameters() { + allowParameters(EngineParameter.API_KEY); + } + + @Override + protected void collectAllowedVehicles(@NonNull List vehicles) { + vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car)); + vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike)); + vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot)); + vehicles.add(new VehicleType("hike", R.string.routing_engine_vehicle_type_hiking)); + vehicles.add(new VehicleType("mtb", R.string.routing_engine_vehicle_type_mtb)); + vehicles.add(new VehicleType("racingbike", R.string.routing_engine_vehicle_type_racingbike)); + vehicles.add(new VehicleType("scooter", R.string.routing_engine_vehicle_type_scooter)); + vehicles.add(new VehicleType("truck", R.string.routing_engine_vehicle_type_truck)); + vehicles.add(new VehicleType("small_truck", R.string.routing_engine_vehicle_type_small_truck)); + } + + @Override + protected void makeFullUrl(@NonNull StringBuilder sb, + @NonNull List path) { + sb.append("?"); + for (LatLon point : path) { + sb.append("point=") + .append(point.getLatitude()) + .append(',') + .append(point.getLongitude()) + .append('&'); + } + String vehicle = get(EngineParameter.VEHICLE_KEY); + if (vehicle != null) { + sb.append("vehicle=").append(vehicle); + } + String apiKey = get(EngineParameter.API_KEY); + if (apiKey != null) { + sb.append('&').append("key=").append(apiKey); + } + } + + @NonNull + @Override + public List parseServerResponse(@NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + return GeoPolylineParserUtil.parse( + obj.getJSONArray("paths").getJSONObject(0).getString("points"), + GeoPolylineParserUtil.PRECISION_5); + } + + @Override + public boolean parseServerMessage(@NonNull StringBuilder sb, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + if (obj.has("message")) { + String message = obj.getString("message"); + sb.append(message); + } + return obj.has("paths"); + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java new file mode 100644 index 0000000000..9072c7ada0 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -0,0 +1,197 @@ +package net.osmand.plus.onlinerouting.engine; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.data.LatLon; +import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingFactory; +import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.util.Algorithms; + +import org.json.JSONException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public abstract class OnlineRoutingEngine implements Cloneable { + + public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; + public static final VehicleType CUSTOM_VEHICLE = new VehicleType("", R.string.shared_string_custom); + + private final Map params = new HashMap<>(); + private final List allowedVehicles = new ArrayList<>(); + private final Set allowedParameters = new HashSet<>(); + + public OnlineRoutingEngine(@Nullable Map params) { + if (!Algorithms.isEmpty(params)) { + this.params.putAll(params); + } + collectAllowedVehiclesInternal(); + collectAllowedParametersInternal(); + } + + @NonNull + public abstract EngineType getType(); + + @Nullable + public String getStringKey() { + return get(EngineParameter.KEY); + } + + @NonNull + public String getName(@NonNull Context ctx) { + String customName = get(EngineParameter.CUSTOM_NAME); + if (customName != null) { + return customName; + } else { + return getStandardName(ctx); + } + } + + @NonNull + private String getStandardName(@NonNull Context ctx) { + String base = getBaseName(ctx); + String index = get(EngineParameter.NAME_INDEX); + return !Algorithms.isEmpty(index) ? base + " " + index : base; + } + + @NonNull + public String getBaseName(@NonNull Context ctx) { + String vehicleTitle = getSelectedVehicleName(ctx); + if (Algorithms.isEmpty(vehicleTitle)) { + return getType().getTitle(); + } else { + String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash); + return String.format(pattern, getType().getTitle(), vehicleTitle); + } + } + + @NonNull + public String getBaseUrl() { + String customUrl = get(EngineParameter.CUSTOM_URL); + if (Algorithms.isEmpty(customUrl)) { + return getStandardUrl(); + } + return customUrl; + } + + @NonNull + public String getFullUrl(@NonNull List path) { + StringBuilder sb = new StringBuilder(getBaseUrl()); + makeFullUrl(sb, path); + return sb.toString(); + } + + protected abstract void makeFullUrl(@NonNull StringBuilder sb, + @NonNull List path); + + @NonNull + public abstract List parseServerResponse(@NonNull String content) throws JSONException; + + @NonNull + public abstract String getStandardUrl(); + + @NonNull + public Map getParams() { + return params; + } + + @Nullable + public String get(@NonNull EngineParameter key) { + return params.get(key.name()); + } + + public void put(@NonNull EngineParameter key, @NonNull String value) { + params.put(key.name(), value); + } + + public void remove(@NonNull EngineParameter key) { + params.remove(key.name()); + } + + private void collectAllowedVehiclesInternal() { + allowedVehicles.clear(); + collectAllowedVehicles(allowedVehicles); + allowedVehicles.add(CUSTOM_VEHICLE); + } + + protected abstract void collectAllowedVehicles(@NonNull List vehicles); + + @NonNull + public List getAllowedVehicles() { + return Collections.unmodifiableList(allowedVehicles); + } + + private void collectAllowedParametersInternal() { + allowedParameters.clear(); + allowParameters(EngineParameter.KEY, EngineParameter.VEHICLE_KEY, + EngineParameter.CUSTOM_NAME, EngineParameter.NAME_INDEX, EngineParameter.CUSTOM_URL); + collectAllowedParameters(); + } + + protected abstract void collectAllowedParameters(); + + public boolean isParameterAllowed(EngineParameter key) { + return allowedParameters.contains(key); + } + + protected void allowParameters(@NonNull EngineParameter ... allowedParams) { + allowedParameters.addAll(Arrays.asList(allowedParams)); + } + + @Nullable + private String getSelectedVehicleName(@NonNull Context ctx) { + String key = get(EngineParameter.VEHICLE_KEY); + VehicleType vt = getVehicleTypeByKey(key); + if (!vt.equals(CUSTOM_VEHICLE)) { + return vt.getTitle(ctx); + } + return key != null ? Algorithms.capitalizeFirstLetter(key) : null; + } + + @NonNull + public VehicleType getSelectedVehicleType() { + String key = get(EngineParameter.VEHICLE_KEY); + return getVehicleTypeByKey(key); + } + + @NonNull + public VehicleType getVehicleTypeByKey(@Nullable String vehicleKey) { + if (!isEmpty(vehicleKey)) { + for (VehicleType vt : allowedVehicles) { + if (Algorithms.objectEquals(vt.getKey(), vehicleKey)) { + return vt; + } + } + } + return CUSTOM_VEHICLE; + } + + public abstract boolean parseServerMessage(@NonNull StringBuilder sb, + @NonNull String content) throws JSONException; + + @NonNull + @Override + public Object clone() { + return OnlineRoutingFactory.createEngine(getType(), getParams()); + } + + protected boolean isEmpty(@Nullable String s) { + return Algorithms.isEmpty(s); + } + + @NonNull + public static String generateKey() { + return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java new file mode 100644 index 0000000000..507ecd3af0 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -0,0 +1,102 @@ +package net.osmand.plus.onlinerouting.engine; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.data.LatLon; +import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.VehicleType; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class OrsEngine extends OnlineRoutingEngine { + + public OrsEngine(@Nullable Map params) { + super(params); + } + + @Override + public @NonNull EngineType getType() { + return EngineType.ORS; + } + + @NonNull + @Override + public String getStandardUrl() { + return "https://api.openrouteservice.org/v2/directions/"; + } + + @Override + protected void collectAllowedParameters() { + allowParameters(EngineParameter.API_KEY); + } + + @Override + protected void collectAllowedVehicles(@NonNull List vehicles) { + vehicles.add(new VehicleType("driving-car", R.string.routing_engine_vehicle_type_car)); + vehicles.add(new VehicleType("driving-hgv", R.string.routing_engine_vehicle_type_hgv)); + vehicles.add(new VehicleType("cycling-regular", R.string.routing_engine_vehicle_type_cycling_regular)); + vehicles.add(new VehicleType("cycling-road", R.string.routing_engine_vehicle_type_cycling_road)); + vehicles.add(new VehicleType("cycling-mountain", R.string.routing_engine_vehicle_type_cycling_mountain)); + vehicles.add(new VehicleType("cycling-electric", R.string.routing_engine_vehicle_type_cycling_electric)); + vehicles.add(new VehicleType("foot-walking", R.string.routing_engine_vehicle_type_walking)); + vehicles.add(new VehicleType("foot-hiking", R.string.routing_engine_vehicle_type_hiking)); + vehicles.add(new VehicleType("wheelchair", R.string.routing_engine_vehicle_type_wheelchair)); + } + + @Override + protected void makeFullUrl(@NonNull StringBuilder sb, + @NonNull List path) { + if (path.size() > 1) { + String vehicleKey = get(EngineParameter.VEHICLE_KEY); + if (!isEmpty(vehicleKey)) { + sb.append(vehicleKey); + } + sb.append('?'); + String apiKey = get(EngineParameter.API_KEY); + if (!isEmpty(apiKey)) { + sb.append("api_key=").append(apiKey); + } + LatLon start = path.get(0); + LatLon end = path.get(path.size() - 1); + sb.append('&').append("start=") + .append(start.getLatitude()).append(',').append(start.getLongitude()); + sb.append('&').append("end=") + .append(end.getLatitude()).append(',').append(end.getLongitude()); + } + } + + @NonNull + @Override + public List parseServerResponse(@NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + JSONArray array = obj.getJSONArray("features").getJSONObject(0) + .getJSONObject("geometry").getJSONArray("coordinates"); + List track = new ArrayList<>(); + for (int i = 0; i < array.length(); i++) { + JSONArray point = array.getJSONArray(i); + double lat = Double.parseDouble(point.getString(0)); + double lon = Double.parseDouble(point.getString(1)); + track.add(new LatLon(lat, lon)); + } + return track; + } + + @Override + public boolean parseServerMessage(@NonNull StringBuilder sb, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + if (obj.has("error")) { + String message = obj.getString("error"); + sb.append(message); + } + return obj.has("features"); + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java new file mode 100644 index 0000000000..d88ae42ff7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -0,0 +1,82 @@ +package net.osmand.plus.onlinerouting.engine; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.data.LatLon; +import net.osmand.plus.R; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.util.GeoPolylineParserUtil; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; + +public class OsrmEngine extends OnlineRoutingEngine { + + public OsrmEngine(@Nullable Map params) { + super(params); + } + + @Override + public @NonNull EngineType getType() { + return EngineType.OSRM; + } + + @NonNull + @Override + public String getStandardUrl() { + return "https://router.project-osrm.org/route/v1/"; + } + + @Override + protected void collectAllowedParameters() { } + + @Override + protected void collectAllowedVehicles(@NonNull List vehicles) { + vehicles.add(new VehicleType("car", R.string.routing_engine_vehicle_type_car)); + vehicles.add(new VehicleType("bike", R.string.routing_engine_vehicle_type_bike)); + vehicles.add(new VehicleType("foot", R.string.routing_engine_vehicle_type_foot)); + } + + @Override + protected void makeFullUrl(@NonNull StringBuilder sb, + @NonNull List path) { + String vehicleKey = get(EngineParameter.VEHICLE_KEY); + if (!isEmpty(vehicleKey)) { + sb.append(vehicleKey).append('/'); + } + for (int i = 0; i < path.size(); i++) { + LatLon point = path.get(i); + sb.append(point.getLongitude()).append(',').append(point.getLatitude()); + if (i < path.size() - 1) { + sb.append(';'); + } + } + sb.append('?'); + sb.append("overview=full"); + } + + @NonNull + @Override + public List parseServerResponse(@NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + return GeoPolylineParserUtil.parse( + obj.getJSONArray("routes").getJSONObject(0).getString("geometry"), + GeoPolylineParserUtil.PRECISION_5); + } + + @Override + public boolean parseServerMessage(@NonNull StringBuilder sb, + @NonNull String content) throws JSONException { + JSONObject obj = new JSONObject(content); + if (obj.has("message")) { + String message = obj.getString("message"); + sb.append(message); + } + return obj.has("routes"); + } +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/ExampleLocation.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/ExampleLocation.java new file mode 100644 index 0000000000..0a384002f7 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/ExampleLocation.java @@ -0,0 +1,52 @@ +package net.osmand.plus.onlinerouting.ui; + +import androidx.annotation.NonNull; + +import net.osmand.data.LatLon; + +public enum ExampleLocation { + + AMSTERDAM("Amsterdam", + new LatLon(52.379189, 4.899431), + new LatLon(52.308056, 4.764167)), + + BERLIN("Berlin", + new LatLon(52.520008, 13.404954), + new LatLon(52.3666652, 13.501997992)), + + NEW_YORK("New York", + new LatLon(43.000000, -75.000000), + new LatLon(40.641766, -73.780968)), + + PARIS("Paris", + new LatLon(48.864716, 2.349014), + new LatLon(48.948437, 2.434931)); + + ExampleLocation(@NonNull String name, + @NonNull LatLon cityCenterLatLon, + @NonNull LatLon cityAirportLatLon) { + this.name = name; + this.cityCenterLatLon = cityCenterLatLon; + this.cityAirportLatLon = cityAirportLatLon; + } + + private String name; + private LatLon cityCenterLatLon; + private LatLon cityAirportLatLon; + + @NonNull + public String getName() { + return name; + } + + @NonNull + public LatLon getCityCenterLatLon() { + return cityCenterLatLon; + } + + @NonNull + public LatLon getCityAirportLatLon() { + return cityAirportLatLon; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java similarity index 81% rename from OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java index 1b9e7f3b29..7a1f4c6b4b 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java @@ -1,4 +1,4 @@ -package net.osmand.plus.onlinerouting; +package net.osmand.plus.onlinerouting.ui; import android.text.Editable; import android.text.TextWatcher; @@ -9,6 +9,7 @@ import android.widget.EditText; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -39,9 +40,11 @@ public class OnlineRoutingCard extends BaseCard { private OsmandTextFieldBoxes textFieldBoxes; private EditText editText; private TextView tvHelperText; + private TextView tvErrorText; private View bottomDivider; private View button; private OnTextChangedListener onTextChangedListener; + private boolean fieldBoxHelperTextShowed; public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode) { super(mapActivity); @@ -64,6 +67,7 @@ public class OnlineRoutingCard extends BaseCard { textFieldBoxes = view.findViewById(R.id.field_box); editText = view.findViewById(R.id.edit_text); tvHelperText = view.findViewById(R.id.helper_text); + tvErrorText = view.findViewById(R.id.error_text); bottomDivider = view.findViewById(R.id.bottom_divider); button = view.findViewById(R.id.button); @@ -80,7 +84,7 @@ public class OnlineRoutingCard extends BaseCard { public void afterTextChanged(Editable s) { if (onTextChangedListener != null) { boolean editedByUser = editText.getTag() == null; - String text = editText.getText().toString(); + String text = editText.getText().toString().trim(); onTextChangedListener.onTextChanged(editedByUser, text); } } @@ -107,9 +111,9 @@ public class OnlineRoutingCard extends BaseCard { tvHeaderSubtitle.setText(subtitle); } - public void setSelectionMenu(List items, - String selectedItemTitle, - final CallbackWithObject callback) { + public void setSelectionMenu(@NonNull List items, + @NonNull String selectedItemTitle, + @NonNull final CallbackWithObject callback) { showElements(rvSelectionMenu); rvSelectionMenu.setLayoutManager( new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); @@ -139,15 +143,31 @@ public class OnlineRoutingCard extends BaseCard { public void setFieldBoxHelperText(@NonNull String helperText) { showElements(fieldBoxContainer, tvHelperText); + fieldBoxHelperTextShowed = true; tvHelperText.setText(helperText); } + public void showFieldBoxError(@NonNull String errorText) { + showElements(fieldBoxContainer, tvErrorText); + hideElements(tvHelperText); + tvErrorText.setText(errorText); + } + + public void hideFieldBoxError() { + hideElements(tvErrorText); + if (fieldBoxHelperTextShowed) { + showElements(tvErrorText); + } + } + public void setEditedText(@NonNull String text) { - editText.setTag(""); // needed to indicate that the text was edited programmatically + showElements(fieldBoxContainer); + editText.setTag(""); // indicate that the text was edited programmatically editText.setText(text); editText.setTag(null); } + @NonNull public String getEditedText() { return editText.getText().toString(); } @@ -156,7 +176,8 @@ public class OnlineRoutingCard extends BaseCard { showElements(bottomDivider); } - public void setButton(String title, OnClickListener listener) { + public void setButton(@NonNull String title, + @NonNull OnClickListener listener) { showElements(button); button.setOnClickListener(listener); UiUtilities.setupDialogButton(nightMode, button, DialogButtonType.PRIMARY, title); @@ -186,11 +207,11 @@ public class OnlineRoutingCard extends BaseCard { AndroidUiHelper.setVisibility(View.GONE, views); } - public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener) { + public void setOnTextChangedListener(@Nullable OnTextChangedListener onTextChangedListener) { this.onTextChangedListener = onTextChangedListener; } public interface OnTextChangedListener { - void onTextChanged(boolean editedByUser, String text); + void onTextChanged(boolean editedByUser, @NonNull String text); } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java similarity index 57% rename from OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java rename to OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index 59df4ef698..f44b936b39 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -1,13 +1,11 @@ -package net.osmand.plus.onlinerouting; +package net.osmand.plus.onlinerouting.ui; -import android.content.Context; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -17,8 +15,6 @@ import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import net.osmand.AndroidNetworkUtils; -import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidUtils; import net.osmand.CallbackWithObject; import net.osmand.data.LatLon; @@ -29,33 +25,37 @@ import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; -import net.osmand.plus.onlinerouting.OnlineRoutingCard.OnTextChangedListener; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingFactory; +import net.osmand.plus.onlinerouting.OnlineRoutingHelper; +import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.ui.OnlineRoutingCard.OnTextChangedListener; +import net.osmand.plus.onlinerouting.engine.EngineType; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.util.Algorithms; import org.json.JSONException; -import org.json.JSONObject; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.CUSTOM_VEHICLE; + public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public static final String TAG = OnlineRoutingEngineFragment.class.getSimpleName(); - private static final String ENGINE_NAME_KEY = "engine_name"; - private static final String ENGINE_SERVER_KEY = "engine_server"; - private static final String ENGINE_SERVER_URL_KEY = "engine_server_url"; - private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type"; + private static final String ENGINE_TYPE_KEY = "engine_type"; private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; - private static final String ENGINE_API_KEY_KEY = "engine_api_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; private static final String EDITED_ENGINE_KEY = "edited_engine_key"; private OsmandApplication app; + private ApplicationMode appMode; private MapActivity mapActivity; private OnlineRoutingHelper helper; @@ -67,61 +67,19 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard exampleCard; private View testResultsContainer; + private View saveButton; - private ApplicationMode appMode; - - private OnlineRoutingEngineObject engine; + private OnlineRoutingEngine engine; + private String customVehicleKey; private ExampleLocation selectedLocation; private String editedEngineKey; - private enum ExampleLocation { - - AMSTERDAM("Amsterdam", - new LatLon(52.379189, 4.899431), - new LatLon(52.308056, 4.764167)), - - BERLIN("Berlin", - new LatLon(52.520008, 13.404954), - new LatLon(52.3666652, 13.501997992)), - - NEW_YORK("New York", - new LatLon(43.000000, -75.000000), - new LatLon(40.641766, -73.780968)), - - PARIS("Paris", - new LatLon(48.864716, 2.349014), - new LatLon(48.948437, 2.434931)); - - ExampleLocation(String name, LatLon cityCenterLatLon, LatLon cityAirportLatLon) { - this.name = name; - this.cityCenterLatLon = cityCenterLatLon; - this.cityAirportLatLon = cityAirportLatLon; - } - - private String name; - private LatLon cityCenterLatLon; - private LatLon cityAirportLatLon; - - public String getName() { - return name; - } - - public LatLon getCityCenterLatLon() { - return cityCenterLatLon; - } - - public LatLon getCityAirportLatLon() { - return cityAirportLatLon; - } - } - @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); app = requireMyApplication(); mapActivity = getMapActivity(); helper = app.getOnlineRoutingHelper(); - engine = new OnlineRoutingEngineObject(); if (savedInstanceState != null) { restoreState(savedInstanceState); } else { @@ -148,14 +106,43 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupApiKeyCard(); setupExampleCard(); setupResultsContainer(); - addSpaceSegment(); - setupButtons(); + generateUniqueNameIfNeeded(); updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); return view; } + private void setupToolbar(Toolbar toolbar) { + ImageView navigationIcon = toolbar.findViewById(R.id.close_button); + navigationIcon.setImageResource(R.drawable.ic_action_close); + navigationIcon.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + TextView title = toolbar.findViewById(R.id.toolbar_title); + toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE); + View actionBtn = toolbar.findViewById(R.id.action_button); + if (isEditingMode()) { + title.setText(getString(R.string.edit_online_routing_engine)); + ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon); + ivBtn.setImageDrawable( + getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete)); + actionBtn.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + onDeleteEngine(); + dismiss(); + } + }); + } else { + title.setText(getString(R.string.add_online_routing_engine)); + actionBtn.setVisibility(View.GONE); + } + } + private void setupNameCard() { nameCard = new OnlineRoutingCard(mapActivity, isNightMode()); nameCard.build(mapActivity); @@ -164,9 +151,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { nameCard.setFieldBoxLabelText(getString(R.string.shared_string_name)); nameCard.setOnTextChangedListener(new OnTextChangedListener() { @Override - public void onTextChanged(boolean changedByUser, String text) { + public void onTextChanged(boolean changedByUser, @NonNull String text) { if (changedByUser) { - engine.customName = text; + engine.put(EngineParameter.CUSTOM_NAME, text); + checkCustomNameUnique(engine); } } }); @@ -182,14 +170,13 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { for (EngineType server : EngineType.values()) { serverItems.add(new HorizontalSelectionItem(server.getTitle(), server)); } - typeCard.setSelectionMenu(serverItems, engine.type.getTitle(), + typeCard.setSelectionMenu(serverItems, engine.getType().getTitle(), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { EngineType type = (EngineType) result.getObject(); - if (engine.type != type) { - engine.type = type; - updateCardViews(nameCard, typeCard, exampleCard); + if (engine.getType() != type) { + changeEngineType(type); return true; } return false; @@ -197,9 +184,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { }); typeCard.setOnTextChangedListener(new OnTextChangedListener() { @Override - public void onTextChanged(boolean editedByUser, String text) { + public void onTextChanged(boolean editedByUser, @NonNull String text) { if (editedByUser) { - engine.customServerUrl = text; + engine.put(EngineParameter.CUSTOM_URL, text); updateCardViews(exampleCard); } } @@ -213,37 +200,44 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode()); vehicleCard.build(mapActivity); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); + vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); + vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { + @Override + public void onTextChanged(boolean editedByUser, @NonNull String text) { + if (editedByUser) { + customVehicleKey = text; + engine.put(EngineParameter.VEHICLE_KEY, customVehicleKey); + updateCardViews(nameCard, exampleCard); + } + } + }); + vehicleCard.setEditedText(customVehicleKey); + vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param)); + vehicleCard.showDivider(); + segmentsContainer.addView(vehicleCard.getView()); + setupVehicleTypes(); + } + + private void setupVehicleTypes() { List vehicleItems = new ArrayList<>(); - for (VehicleType vehicle : VehicleType.values()) { + for (VehicleType vehicle : engine.getAllowedVehicles()) { vehicleItems.add(new HorizontalSelectionItem(vehicle.getTitle(app), vehicle)); } - vehicleCard.setSelectionMenu(vehicleItems, engine.vehicleType.getTitle(app), + vehicleCard.setSelectionMenu(vehicleItems, engine.getSelectedVehicleType().getTitle(app), new CallbackWithObject() { @Override public boolean processResult(HorizontalSelectionItem result) { VehicleType vehicle = (VehicleType) result.getObject(); - if (engine.vehicleType != vehicle) { - engine.vehicleType = vehicle; + if (!Algorithms.objectEquals(engine.getSelectedVehicleType(), vehicle)) { + String vehicleKey = vehicle.equals(CUSTOM_VEHICLE) ? customVehicleKey : vehicle.getKey(); + engine.put(EngineParameter.VEHICLE_KEY, vehicleKey); + generateUniqueNameIfNeeded(); updateCardViews(nameCard, vehicleCard, exampleCard); return true; } return false; } }); - vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); - vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { - @Override - public void onTextChanged(boolean editedByUser, String text) { - if (editedByUser) { - engine.customVehicleKey = text; - updateCardViews(nameCard, exampleCard); - } - } - }); - vehicleCard.setEditedText(engine.customVehicleKey); - vehicleCard.setFieldBoxHelperText(getString(R.string.shared_string_enter_param)); - vehicleCard.showDivider(); - segmentsContainer.addView(vehicleCard.getView()); } private void setupApiKeyCard() { @@ -251,12 +245,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { apiKeyCard.build(mapActivity); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); - apiKeyCard.setEditedText(engine.apiKey); + String apiKey = engine.get(EngineParameter.API_KEY); + if (apiKey != null) { + apiKeyCard.setEditedText(apiKey); + } apiKeyCard.showDivider(); apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() { @Override - public void onTextChanged(boolean editedByUser, String text) { - engine.apiKey = text; + public void onTextChanged(boolean editedByUser, @NonNull String text) { + engine.put(EngineParameter.API_KEY, text); updateCardViews(exampleCard); } }); @@ -297,86 +294,10 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private void setupResultsContainer() { testResultsContainer = getInflater().inflate( R.layout.bottom_sheet_item_with_descr_64dp, segmentsContainer, false); - testResultsContainer.setVisibility(View.GONE); + testResultsContainer.setVisibility(View.INVISIBLE); segmentsContainer.addView(testResultsContainer); } - private void addSpaceSegment() { - int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top); - View bottomSpaceView = new View(app); - bottomSpaceView.setLayoutParams( - new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, space)); - segmentsContainer.addView(bottomSpaceView); - } - - private void setupToolbar(Toolbar toolbar) { - ImageView navigationIcon = toolbar.findViewById(R.id.close_button); - navigationIcon.setImageResource(R.drawable.ic_action_close); - navigationIcon.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - TextView title = toolbar.findViewById(R.id.toolbar_title); - toolbar.findViewById(R.id.toolbar_subtitle).setVisibility(View.GONE); - View actionBtn = toolbar.findViewById(R.id.action_button); - if (isEditingMode()) { - title.setText(getString(R.string.edit_online_routing_engine)); - ImageView ivBtn = toolbar.findViewById(R.id.action_button_icon); - ivBtn.setImageDrawable( - getIcon(R.drawable.ic_action_delete_dark, R.color.color_osm_edit_delete)); - actionBtn.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - deleteEngine(); - dismiss(); - } - }); - } else { - title.setText(getString(R.string.add_online_routing_engine)); - actionBtn.setVisibility(View.GONE); - } - } - - private void updateCardViews(BaseCard... cardsToUpdate) { - for (BaseCard card : cardsToUpdate) { - if (nameCard.equals(card)) { - if (Algorithms.isEmpty(engine.customName)) { - String name; - if (Algorithms.isEmpty(engine.getVehicleKey())) { - name = engine.type.getTitle(); - } else { - name = OnlineRoutingEngine.getStandardName(app, engine.type, engine.getVehicleKey()); - } - nameCard.setEditedText(name); - } - - } else if (typeCard.equals(card)) { - typeCard.setHeaderSubtitle(engine.type.getTitle()); - typeCard.setEditedText(engine.getBaseUrl()); - if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) { - apiKeyCard.show(); - } else { - apiKeyCard.hide(); - } - - } else if (vehicleCard.equals(card)) { - VehicleType vt = VehicleType.getVehicleByKey(engine.getVehicleKey()); - vehicleCard.setHeaderSubtitle(vt.getTitle(app)); - if (vt == VehicleType.CUSTOM) { - vehicleCard.showFieldBox(); - vehicleCard.setEditedText(engine.getVehicleKey()); - } else { - vehicleCard.hideFieldBox(); - } - - } else if (exampleCard.equals(card)) { - exampleCard.setEditedText(getTestUrl()); - } - } - } - private void setupButtons() { boolean nightMode = isNightMode(); View cancelButton = view.findViewById(R.id.dismiss_button); @@ -391,149 +312,167 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { view.findViewById(R.id.buttons_divider).setVisibility(View.VISIBLE); - View saveButton = view.findViewById(R.id.right_bottom_button); + saveButton = view.findViewById(R.id.right_bottom_button); UiUtilities.setupDialogButton(nightMode, saveButton, UiUtilities.DialogButtonType.PRIMARY, R.string.shared_string_save); saveButton.setVisibility(View.VISIBLE); saveButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - saveChanges(); + onSaveEngine(); dismiss(); } }); } - private void saveChanges() { - OnlineRoutingEngine engineToSave; - if (isEditingMode()) { - engineToSave = new OnlineRoutingEngine(editedEngineKey, engine.type, engine.getVehicleKey()); + private void changeEngineType(EngineType type) { + OnlineRoutingEngine tmp = (OnlineRoutingEngine) engine.clone(); + engine = OnlineRoutingFactory.createEngine(type, tmp.getParams()); + + // after changing the type, select the vehicle + // with the same name that was selected before + VehicleType previous = tmp.getSelectedVehicleType(); + VehicleType next = null; + for (VehicleType vt : engine.getAllowedVehicles()) { + if (Algorithms.objectEquals(previous.getTitle(app), vt.getTitle(app))) { + next = vt; + break; + } + } + String vehicleKey; + if (next != null) { + vehicleKey = next.equals(CUSTOM_VEHICLE) ? customVehicleKey : next.getKey(); } else { - engineToSave = OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null); + vehicleKey = engine.getAllowedVehicles().get(0).getKey(); } + engine.put(EngineParameter.VEHICLE_KEY, vehicleKey); - engineToSave.putParameter(EngineParameter.CUSTOM_NAME, engine.customName); - engineToSave.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); - if (engine.type == EngineType.GRAPHHOPPER || engine.type == EngineType.ORS) { - engineToSave.putParameter(EngineParameter.API_KEY, engine.apiKey); + setupVehicleTypes(); + generateUniqueNameIfNeeded(); + updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); + } + + private void generateUniqueNameIfNeeded() { + if (engine.get(EngineParameter.CUSTOM_NAME) == null) { + engine.remove(EngineParameter.NAME_INDEX); + if (hasNameDuplicate(engine.getName(app))) { + int index = 0; + do { + engine.put(EngineParameter.NAME_INDEX, String.valueOf(++index)); + } while (hasNameDuplicate(engine.getName(app))); + } } - - helper.saveEngine(engineToSave); } - private void deleteEngine() { - helper.deleteEngine(editedEngineKey); - } - - private String getTestUrl() { - List path = new ArrayList<>(); - path.add(selectedLocation.getCityCenterLatLon()); - path.add(selectedLocation.getCityAirportLatLon()); - OnlineRoutingEngine tmpEngine = - OnlineRoutingEngine.createNewEngine(engine.type, engine.getVehicleKey(), null); - tmpEngine.putParameter(EngineParameter.CUSTOM_URL, engine.customServerUrl); - tmpEngine.putParameter(EngineParameter.API_KEY, engine.apiKey); - return helper.createFullUrl(tmpEngine, path); - } - - private void testEngineWork() { - final EngineType type = engine.type; - final ExampleLocation location = selectedLocation; - AndroidNetworkUtils.sendRequestAsync(app, exampleCard.getEditedText(), null, - null, false, false, new OnRequestResultListener() { - @Override - public void onResult(String response) { - boolean resultOk = false; - if (response != null) { - try { - JSONObject obj = new JSONObject(response); - - if (type == EngineType.GRAPHHOPPER) { - resultOk = obj.has("paths"); - } else if (type == EngineType.OSRM) { - resultOk = obj.has("routes"); - } else if (type == EngineType.ORS) { - resultOk = obj.has("features"); - } - } catch (JSONException e) { - - } - } - showTestResults(resultOk, location); - } - }); - } - - private void showTestResults(boolean resultOk, ExampleLocation location) { - testResultsContainer.setVisibility(View.VISIBLE); - ImageView ivImage = testResultsContainer.findViewById(R.id.icon); - TextView tvTitle = testResultsContainer.findViewById(R.id.title); - TextView tvDescription = testResultsContainer.findViewById(R.id.description); - if (resultOk) { - ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_gdirections_dark)); - tvTitle.setText(getString(R.string.shared_string_ok)); + private void checkCustomNameUnique(@NonNull OnlineRoutingEngine engine) { + if (hasNameDuplicate(engine.getName(app))) { + nameCard.showFieldBoxError(getString(R.string.message_name_is_already_exists)); + saveButton.setEnabled(false); } else { - ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert)); - tvTitle.setText(getString(R.string.message_error_recheck_parameters)); + nameCard.hideFieldBoxError(); + saveButton.setEnabled(true); } - tvDescription.setText(location.getName()); + } + + private boolean hasNameDuplicate(@NonNull String name) { + for (OnlineRoutingEngine engine : helper.getEnginesExceptMentioned(editedEngineKey)) { + if (Algorithms.objectEquals(engine.getName(app), name)) { + return true; + } + } + return false; + } + + private void onSaveEngine() { + if (engine != null) { + helper.saveEngine(engine); + } + } + + private void onDeleteEngine() { + helper.deleteEngine(engine); } private boolean isEditingMode() { return editedEngineKey != null; } - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - saveState(outState); + private String getTestUrl() { + List path = new ArrayList<>(); + path.add(selectedLocation.getCityCenterLatLon()); + path.add(selectedLocation.getCityAirportLatLon()); + return engine.getFullUrl(path); } - private void saveState(Bundle outState) { - outState.putString(ENGINE_NAME_KEY, engine.customName); - outState.putString(ENGINE_SERVER_KEY, engine.type.name()); - outState.putString(ENGINE_SERVER_URL_KEY, engine.customServerUrl); - outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); - outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); - outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); - outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); - if (appMode != null) { - outState.putString(APP_MODE_KEY, appMode.getStringKey()); - } - outState.putString(EDITED_ENGINE_KEY, editedEngineKey); - } - - private void restoreState(Bundle savedState) { - engine.customName = savedState.getString(ENGINE_NAME_KEY); - engine.type = EngineType.valueOf(savedState.getString(ENGINE_SERVER_KEY)); - engine.customServerUrl = savedState.getString(ENGINE_SERVER_URL_KEY); - engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); - engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); - engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); - selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); - appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); - editedEngineKey = savedState.getString(EDITED_ENGINE_KEY); - } - - private void initState() { - engine.type = EngineType.values()[0]; - engine.vehicleType = VehicleType.values()[0]; - selectedLocation = ExampleLocation.values()[0]; - - if (isEditingMode()) { - OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); - if (editedEngine != null) { - engine.customName = editedEngine.getParameter(EngineParameter.CUSTOM_NAME); - engine.type = editedEngine.getType(); - String vehicleKey = editedEngine.getVehicleKey(); - if (vehicleKey != null) { - VehicleType vehicleType = VehicleType.getVehicleByKey(vehicleKey); - if (vehicleType == VehicleType.CUSTOM) { - engine.customVehicleKey = vehicleKey; - } - engine.vehicleType = vehicleType; + private void testEngineWork() { + final OnlineRoutingEngine requestedEngine = (OnlineRoutingEngine) engine.clone(); + final ExampleLocation location = selectedLocation; + new Thread(new Runnable() { + @Override + public void run() { + StringBuilder message = new StringBuilder(); + boolean resultOk = false; + try { + String response = helper.makeRequest(exampleCard.getEditedText()); + resultOk = requestedEngine.parseServerMessage(message, response); + } catch (IOException | JSONException e) { + message.append(e.toString()); } - engine.apiKey = editedEngine.getParameter(EngineParameter.API_KEY); + showTestResults(resultOk, message.toString(), location); + } + }).start(); + } + + private void showTestResults(final boolean resultOk, + final @NonNull String message, + final @NonNull ExampleLocation location) { + app.runInUIThread(new Runnable() { + @Override + public void run() { + testResultsContainer.setVisibility(View.VISIBLE); + ImageView ivImage = testResultsContainer.findViewById(R.id.icon); + TextView tvTitle = testResultsContainer.findViewById(R.id.title); + TextView tvDescription = testResultsContainer.findViewById(R.id.description); + if (resultOk) { + ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_gdirections_dark)); + tvTitle.setText(getString(R.string.shared_string_ok)); + } else { + ivImage.setImageDrawable(getContentIcon(R.drawable.ic_action_alert)); + tvTitle.setText(String.format(getString(R.string.message_server_error), message)); + } + tvDescription.setText(location.getName()); + } + }); + } + + private void updateCardViews(@NonNull BaseCard... cardsToUpdate) { + for (BaseCard card : cardsToUpdate) { + if (nameCard.equals(card)) { + if (Algorithms.isEmpty(engine.get(EngineParameter.CUSTOM_NAME))) { + nameCard.setEditedText(engine.getName(app)); + } + + } else if (typeCard.equals(card)) { + typeCard.setHeaderSubtitle(engine.getType().getTitle()); + typeCard.setEditedText(engine.getBaseUrl()); + if (engine.isParameterAllowed(EngineParameter.API_KEY)) { + apiKeyCard.show(); + } else { + apiKeyCard.hide(); + } + + } else if (vehicleCard.equals(card)) { + VehicleType vt = engine.getSelectedVehicleType(); + vehicleCard.setHeaderSubtitle(vt.getTitle(app)); + if (vt.equals(CUSTOM_VEHICLE)) { + vehicleCard.showFieldBox(); + vehicleCard.setEditedText(customVehicleKey); + } else { + vehicleCard.hideFieldBox(); + } + + } else if (exampleCard.equals(card)) { + exampleCard.setEditedText(getTestUrl()); } } } @@ -546,7 +485,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private boolean isNightMode() { - return !app.getSettings().isLightContentForMode(appMode); + return !app.getSettings().isLightContentForMode(getAppMode()); + } + + @NonNull + private ApplicationMode getAppMode() { + return appMode != null ? appMode : app.getSettings().getApplicationMode(); } @Nullable @@ -563,9 +507,64 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return UiUtilities.getInflater(mapActivity, isNightMode()); } + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + saveState(outState); + } + + private void saveState(@NonNull Bundle outState) { + outState.putString(ENGINE_TYPE_KEY, engine.getType().name()); + for (EngineParameter key : EngineParameter.values()) { + String value = engine.get(key); + if (value != null) { + outState.putString(key.name(), value); + } + } + outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, customVehicleKey); + outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); + outState.putString(APP_MODE_KEY, getAppMode().getStringKey()); + outState.putString(EDITED_ENGINE_KEY, editedEngineKey); + } + + private void restoreState(@NonNull Bundle savedState) { + String typeKey = savedState.getString(ENGINE_TYPE_KEY); + EngineType type = EngineType.getTypeByName(typeKey); + engine = OnlineRoutingFactory.createEngine(type); + for (EngineParameter key : EngineParameter.values()) { + String value = savedState.getString(key.name()); + if (value != null) { + engine.put(key, value); + } + } + customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); + selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); + appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); + editedEngineKey = savedState.getString(EngineParameter.KEY.name()); + } + + private void initState() { + selectedLocation = ExampleLocation.values()[0]; + OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); + if (editedEngine != null) { + engine = (OnlineRoutingEngine) editedEngine.clone(); + if (Algorithms.objectEquals(engine.getSelectedVehicleType(), CUSTOM_VEHICLE)) { + customVehicleKey = engine.get(EngineParameter.VEHICLE_KEY); + } + } else { + engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]); + String vehicle = engine.getAllowedVehicles().get(0).getKey(); + engine.put(EngineParameter.VEHICLE_KEY, vehicle); + customVehicleKey = ""; + if (editedEngineKey != null) { + engine.put(EngineParameter.KEY, editedEngineKey); + } + } + } + public static void showInstance(@NonNull FragmentActivity activity, @NonNull ApplicationMode appMode, - String editedEngineKey) { + @Nullable String editedEngineKey) { FragmentManager fm = activity.getSupportFragmentManager(); if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) { OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); @@ -576,34 +575,4 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { .addToBackStack(TAG).commitAllowingStateLoss(); } } - - private static class OnlineRoutingEngineObject { - private String customName; - private EngineType type; - private String customServerUrl; - private VehicleType vehicleType; - private String customVehicleKey; - private String apiKey; - - public String getVehicleKey() { - if (vehicleType == VehicleType.CUSTOM) { - return customVehicleKey; - } - return vehicleType.getKey(); - } - - public String getName(Context ctx) { - if (customName != null) { - return customName; - } - return OnlineRoutingEngine.getStandardName(ctx, type, getVehicleKey()); - } - - public String getBaseUrl() { - if (Algorithms.isEmpty(customServerUrl)) { - return type.getStandardUrl(); - } - return customServerUrl; - } - } } diff --git a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java index 46a35ea67e..86b79ed910 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java @@ -1,12 +1,27 @@ package net.osmand.plus.profiles; +import androidx.annotation.NonNull; + import net.osmand.plus.R; public class OnlineRoutingEngineDataObject extends ProfileDataObject { + private int order; + public OnlineRoutingEngineDataObject(String name, String description, - String stringKey) { + String stringKey, + int order) { super(name, description, stringKey, R.drawable.ic_world_globe_dark, false, null); + this.order = order; + } + + @Override + public int compareTo(@NonNull ProfileDataObject another) { + if (another instanceof OnlineRoutingEngineDataObject) { + OnlineRoutingEngineDataObject anotherEngine = (OnlineRoutingEngineDataObject) another; + return Integer.compare(this.order, anotherEngine.order); + } + return 0; } } diff --git a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java index 28967ba2f3..6306dee9cc 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java +++ b/OsmAnd/src/net/osmand/plus/profiles/ProfileDataUtils.java @@ -5,7 +5,7 @@ import android.content.Context; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.profiles.RoutingProfileDataObject.RoutingProfilesResources; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.router.GeneralRouter; @@ -56,7 +56,22 @@ public class ProfileDataUtils { Collections.sort(fileNames, new Comparator() { @Override public int compare(String s, String t1) { - return s.equals(OSMAND_NAVIGATION) ? -1 : t1.equals(OSMAND_NAVIGATION) ? 1 : s.compareToIgnoreCase(t1); + // OsmAnd navigation should be at the top of the list + if (s.equals(OSMAND_NAVIGATION)) { + return -1; + } else if (t1.equals(OSMAND_NAVIGATION)) { + return 1; + + // Online navigation should be at the bottom of the list + } else if (s.equals(ONLINE_NAVIGATION)) { + return 1; + } else if (t1.equals(ONLINE_NAVIGATION)) { + return -1; + + // Other sorted by file names + } else { + return s.compareToIgnoreCase(t1); + } } }); for (String fileName : fileNames) { @@ -71,9 +86,11 @@ public class ProfileDataUtils { public static List getOnlineRoutingProfiles(OsmandApplication app) { List objects = new ArrayList<>(); - for (OnlineRoutingEngine engine : app.getOnlineRoutingHelper().getEngines()) { + List engines = app.getOnlineRoutingHelper().getEngines(); + for (int i = 0; i < engines.size(); i++) { + OnlineRoutingEngine engine = engines.get(i); objects.add(new OnlineRoutingEngineDataObject( - engine.getName(app), engine.getBaseUrl(), engine.getStringKey())); + engine.getName(app), engine.getBaseUrl(), engine.getStringKey(), i)); } return objects; } diff --git a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java index 98ca4771cc..eb97a8ae85 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/profiles/SelectProfileBottomSheet.java @@ -39,8 +39,9 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet; -import net.osmand.plus.onlinerouting.OnlineRoutingEngineFragment; +import net.osmand.plus.onlinerouting.ui.OnlineRoutingEngineFragment; import net.osmand.router.RoutingConfiguration; +import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -250,7 +251,7 @@ public class SelectProfileBottomSheet extends BasePreferenceBottomSheet { tvTitle.setText(profile.getName()); tvDescription.setText(profile.getDescription()); - boolean isSelected = setupSelected && profile.getStringKey().equals(selectedItemKey); + boolean isSelected = setupSelected && Algorithms.objectEquals(profile.getStringKey(), selectedItemKey); int iconColor; if (dialogMode == DialogMode.NAVIGATION_PROFILE) { iconColor = isSelected ? activeColorResId : iconDefaultColorResId; diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index 89c17f1c2b..96017bc96c 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -2,7 +2,6 @@ package net.osmand.plus.routing; import android.content.Context; -import android.os.Build; import android.os.Bundle; import android.util.Base64; @@ -20,16 +19,14 @@ import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.LatLon; import net.osmand.data.LocationPoint; import net.osmand.data.WptLocationPoint; -import net.osmand.osm.io.NetworkUtils; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.TargetPointsHelper.TargetPoint; -import net.osmand.plus.Version; import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.router.GeneralRouter; @@ -48,21 +45,16 @@ import net.osmand.router.RoutingConfiguration.Builder; import net.osmand.router.RoutingContext; import net.osmand.router.TurnType; import net.osmand.util.Algorithms; -import net.osmand.util.GeoPolylineParserUtil; import net.osmand.util.MapUtils; import org.json.JSONException; -import org.json.JSONObject; import org.xml.sax.SAXException; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.MalformedURLException; -import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1210,8 +1202,12 @@ public class RouteProvider { private RouteCalculationResult findOnlineRoute(RouteCalculationParams params) throws IOException, JSONException { OnlineRoutingHelper helper = params.ctx.getOnlineRoutingHelper(); String stringKey = params.mode.getRoutingProfile(); - List route = helper.calculateRouteOnline(helper.getEngineByKey(stringKey), getFullPathFromParams(params)); - if (!route.isEmpty()) { + OnlineRoutingEngine engine = helper.getEngineByKey(stringKey); + List route = null; + if (engine != null) { + route = helper.calculateRouteOnline(engine, getFullPathFromParams(params)); + } + if (!Algorithms.isEmpty(route)) { List res = new ArrayList<>(); for (LatLon pt : route) { WptPt wpt = new WptPt(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java index 779a97d1df..fc71e8d183 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java @@ -7,8 +7,9 @@ import androidx.annotation.Nullable; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine; -import net.osmand.plus.onlinerouting.OnlineRoutingEngine.EngineParameter; +import net.osmand.plus.onlinerouting.EngineParameter; +import net.osmand.plus.onlinerouting.OnlineRoutingFactory; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import org.json.JSONException; @@ -93,8 +94,8 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem Date: Sat, 16 Jan 2021 01:15:49 +0100 Subject: [PATCH 10/31] fixed xml schema by changing the order of wpt rte and trk and adding the osmand namespace to the route and types extensions --- .../main/java/net/osmand/GPXUtilities.java | 39 +++++++++---------- .../net/osmand/binary/StringBundleWriter.java | 2 +- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index bee9fa2b19..ede3b6f8cf 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -1822,6 +1822,25 @@ public class GPXUtilities { } serializer.endTag(null, "metadata"); + for (WptPt l : file.points) { + serializer.startTag(null, "wpt"); //$NON-NLS-1$ + writeWpt(format, serializer, l); + serializer.endTag(null, "wpt"); //$NON-NLS-1$ + } + + for (Route track : file.routes) { + serializer.startTag(null, "rte"); //$NON-NLS-1$ + writeNotNullText(serializer, "name", track.name); + writeNotNullText(serializer, "desc", track.desc); + + for (WptPt p : track.points) { + serializer.startTag(null, "rtept"); //$NON-NLS-1$ + writeWpt(format, serializer, p); + serializer.endTag(null, "rtept"); //$NON-NLS-1$ + } + writeExtensions(serializer, track); + serializer.endTag(null, "rte"); //$NON-NLS-1$ + } for (Track track : file.tracks) { if (!track.generalTrack) { @@ -1844,26 +1863,6 @@ public class GPXUtilities { } } - for (Route track : file.routes) { - serializer.startTag(null, "rte"); //$NON-NLS-1$ - writeNotNullText(serializer, "name", track.name); - writeNotNullText(serializer, "desc", track.desc); - - for (WptPt p : track.points) { - serializer.startTag(null, "rtept"); //$NON-NLS-1$ - writeWpt(format, serializer, p); - serializer.endTag(null, "rtept"); //$NON-NLS-1$ - } - writeExtensions(serializer, track); - serializer.endTag(null, "rte"); //$NON-NLS-1$ - } - - for (WptPt l : file.points) { - serializer.startTag(null, "wpt"); //$NON-NLS-1$ - writeWpt(format, serializer, l); - serializer.endTag(null, "wpt"); //$NON-NLS-1$ - } - writeExtensions(serializer, file); serializer.endTag(null, "gpx"); //$NON-NLS-1$ diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/StringBundleWriter.java b/OsmAnd-java/src/main/java/net/osmand/binary/StringBundleWriter.java index 2f607aef3a..d3c151c12a 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/StringBundleWriter.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/StringBundleWriter.java @@ -20,7 +20,7 @@ public abstract class StringBundleWriter { public void writeBundle() { for (Entry> entry : bundle.getMap().entrySet()) { - writeItem(entry.getKey(), entry.getValue()); + writeItem("osmand:" + entry.getKey(), entry.getValue()); } } } From 7e3d3b9e79272bbb7617663a8bdd7ecbb1678c8f Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 18 Jan 2021 09:22:21 +0200 Subject: [PATCH 11/31] init --- ...h_switch_divider_and_additional_button.xml | 74 ++++ OsmAnd/res/layout/trip_recording_fragment.xml | 101 ++++++ OsmAnd/res/values/strings.xml | 2 + .../osmand/plus/activities/MapActivity.java | 6 +- .../monitoring/OsmandMonitoringPlugin.java | 25 +- .../monitoring/TripRecordingBottomSheet.java | 335 ++++++++++++++++++ .../plus/track/TrackAppearanceFragment.java | 12 +- 7 files changed, 535 insertions(+), 20 deletions(-) create mode 100644 OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml create mode 100644 OsmAnd/res/layout/trip_recording_fragment.xml create mode 100644 OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java diff --git a/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml new file mode 100644 index 0000000000..f0ff17170d --- /dev/null +++ b/OsmAnd/res/layout/bottom_sheet_with_switch_divider_and_additional_button.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/layout/trip_recording_fragment.xml b/OsmAnd/res/layout/trip_recording_fragment.xml new file mode 100644 index 0000000000..d87a697a9d --- /dev/null +++ b/OsmAnd/res/layout/trip_recording_fragment.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index bbb71f001a..299e7aa5b2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,8 @@ --> + Show track on map + Start recording Announcement time Announcement time of different voice prompts depends on prompt type, current navigation speed and default navigation speed. Time and distance intervals diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 0f27fc6e26..007280144e 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -118,6 +118,7 @@ import net.osmand.plus.measurementtool.LoginBottomSheetFragment; import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.SnapTrackWarningFragment; +import net.osmand.plus.monitoring.TripRecordingBottomSheet; import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.routepreparationmenu.ChooseRouteFragment; @@ -2205,6 +2206,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return getFragment(MeasurementToolFragment.TAG); } + public TripRecordingBottomSheet getTripRecordingBottomSheet() { + return getFragment(TripRecordingBottomSheet.TAG); + } + public ChooseRouteFragment getChooseRouteFragment() { return getFragment(ChooseRouteFragment.TAG); } @@ -2221,7 +2226,6 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return getFragment(SnapTrackWarningFragment.TAG); } - @NonNull public TrackMenuFragment getTrackMenuFragment() { return getFragment(TrackMenuFragment.TAG); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 16c60911df..4a496f6475 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -100,12 +100,12 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { public void updateLocation(Location location) { liveMonitoringHelper.updateLocation(location); } - + @Override public int getLogoResourceId() { return R.drawable.ic_action_gps_info; } - + @Override public Drawable getAssetResourceImage() { return app.getUIUtilities().getIcon(R.drawable.trip_recording); @@ -140,7 +140,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { private void registerWidget(MapActivity activity) { MapInfoLayer layer = activity.getMapLayers().getMapInfoLayer(); monitoringControl = createMonitoringControl(activity); - + layer.registerSideWidget(monitoringControl, R.drawable.ic_action_play_dark, R.string.map_widget_monitoring, "monitoring", false, 30); layer.recreateControls(); @@ -161,7 +161,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { } } } - + public static final int[] SECONDS = new int[] {0, 1, 2, 3, 5, 10, 15, 20, 30, 60, 90}; public static final int[] MINUTES = new int[] {2, 3, 5}; public static final int[] MAX_INTERVAL_TO_SEND_MINUTES = new int[] {1, 2, 5, 10, 15, 20, 30, 60, 90, 2 * 60, 3 * 60, 4 * 60, 6 * 60, 12 * 60, 24 * 60}; @@ -287,7 +287,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { controlDialog(map, true); } - + }); return monitoringControl; } @@ -422,7 +422,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { public void saveCurrentTrack() { saveCurrentTrack(null, null); } - + public void saveCurrentTrack(@Nullable final Runnable onComplete) { saveCurrentTrack(onComplete, null); } @@ -464,7 +464,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { SaveGPXBottomSheetFragment.showInstance(((FragmentActivity) a).getSupportFragmentManager(), result.getFilenames()); } } - + if (onComplete != null) { onComplete.run(); } @@ -506,14 +506,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { if (choice.value || map == null) { runnable.run(); } else { - showIntervalChooseDialog(map, app.getString(R.string.save_track_interval_globally) + " : %s", - app.getString(R.string.save_track_to_gpx_globally), SECONDS, MINUTES, choice, vs, showTrackSelection, - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - runnable.run(); - } - }); + TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); } } @@ -588,7 +581,7 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { tv.setText(String.format(patternMsg, s)); } }); - + for (int i = 0; i < secondsLength + minutesLength - 1; i++) { if (i < secondsLength) { if (v.value <= seconds[i] * 1000) { diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java new file mode 100644 index 0000000000..127729dc64 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -0,0 +1,335 @@ +package net.osmand.plus.monitoring; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Color; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.text.SpannableString; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.FragmentManager; + +import com.google.android.material.slider.RangeSlider; + +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.NavigationService; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.FontCache; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.track.TrackAppearanceFragment; + +import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT; +import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD; +import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM; +import static net.osmand.plus.monitoring.OsmandMonitoringPlugin.MINUTES; +import static net.osmand.plus.monitoring.OsmandMonitoringPlugin.SECONDS; + +public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = TripRecordingBottomSheet.class.getSimpleName(); + + private OsmandApplication app; + private OsmandSettings settings; + + private ImageView upDownBtn; + private SwitchCompat confirmEveryRun; + + private boolean infoExpanded; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = requiredMyApplication(); + settings = app.getSettings(); + Context context = requireContext(); + + LayoutInflater inflater = UiUtilities.getInflater(context, nightMode); + View itemView = inflater.inflate(R.layout.trip_recording_fragment, null, false); + items.add(new BottomSheetItemWithDescription.Builder() + .setCustomView(itemView) + .create()); + + int padding = getResources().getDimensionPixelSize(R.dimen.content_padding_small); + final int paddingSmall = getResources().getDimensionPixelSize(R.dimen.content_padding_small); + + items.add(new DividerSpaceItem(context, padding)); + + LinearLayout showTrackOnMapView = itemView.findViewById(R.id.show_track_on_map); + TextView showTrackOnMapTitle = showTrackOnMapView.findViewById(R.id.title); + showTrackOnMapTitle.setText(R.string.show_track_on_map); + + ImageView trackAppearanceIcon = showTrackOnMapView.findViewById(R.id.icon_after_divider); + Drawable drawable = app.getUIUtilities().getIcon(R.drawable.ic_action_track_line_bold_direction, + nightMode ? R.color.profile_icon_color_red_dark : R.color.profile_icon_color_red_light); + trackAppearanceIcon.setImageDrawable(drawable); + trackAppearanceIcon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + hide(); + SelectedGpxFile selectedGpxFile = app.getSavingTrackHelper().getCurrentTrack(); + TrackAppearanceFragment.showInstance(mapActivity, selectedGpxFile); + } + } + }); + + upDownBtn = itemView.findViewById(R.id.up_down_button); + upDownBtn.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + toggleInfoView(); + } + }); + + final int secondsLength = SECONDS.length; + final int minutesLength = MINUTES.length; + + RangeSlider intervalSlider = itemView.findViewById(R.id.interval_slider); + final TextView intervalValueView = itemView.findViewById(R.id.interval_value_view); + String text = getString(R.string.save_track_interval_globally); + String textValue = getString(R.string.int_continuosly); + String textAll = getString(R.string.ltr_or_rtl_combine_via_colon, text, textValue); + Typeface typeface = FontCache.getRobotoMedium(app); + SpannableString spannableString = UiUtilities.createCustomFontSpannable(typeface, textAll, textValue); + intervalValueView.setText(spannableString); + intervalSlider.setValueTo(secondsLength + minutesLength - 1); + intervalSlider.addOnChangeListener(new RangeSlider.OnChangeListener() { + + @Override + public void onValueChange(@NonNull RangeSlider slider, float value, boolean fromUser) { + String s; + int progress = (int) value; + if (progress == 0) { + s = getString(R.string.int_continuosly); + settings.SAVE_GLOBAL_TRACK_INTERVAL.set(0); + } else { + if (progress < secondsLength) { + s = SECONDS[progress] + " " + getString(R.string.int_seconds); + settings.SAVE_GLOBAL_TRACK_INTERVAL.set(SECONDS[progress] * 1000); + } else { + s = MINUTES[progress - secondsLength] + " " + getString(R.string.int_min); + settings.SAVE_GLOBAL_TRACK_INTERVAL.set(MINUTES[progress - secondsLength] * 60 * 1000); + } + } + intervalValueView.setText(String.format(" : %s", s)); + } + }); + for (int i = 0; i < secondsLength + minutesLength - 1; i++) { + if (i < secondsLength) { + if (settings.SAVE_GLOBAL_TRACK_INTERVAL.get() <= SECONDS[i] * 1000) { + intervalSlider.setValues((float) i); + break; + } + } else { + if (settings.SAVE_GLOBAL_TRACK_INTERVAL.get() <= MINUTES[i - secondsLength] * 1000 * 60) { + intervalSlider.setValues((float) i); + break; + } + } + } + boolean checked = !settings.SAVE_GLOBAL_TRACK_REMEMBER.get(); + confirmEveryRun = itemView.findViewById(R.id.confirm_every_run); + confirmEveryRun.setBackgroundResource(nightMode ? R.drawable.layout_bg_dark : R.drawable.layout_bg); + confirmEveryRun.setChecked(checked); + confirmEveryRun.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + setBackgroundAndPadding(isChecked, paddingSmall); + settings.SAVE_GLOBAL_TRACK_REMEMBER.set(!isChecked); + } + }); + setBackgroundAndPadding(checked, paddingSmall); + UiUtilities.setupCompoundButton(confirmEveryRun, nightMode, PROFILE_DEPENDENT); + + SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); + showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); + showTrackOnMapButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + app.getSelectedGpxHelper().selectGpxFile(app.getSavingTrackHelper().getCurrentGpx(), isChecked, false); + } + }); + UiUtilities.setupCompoundButton(showTrackOnMapButton, nightMode, PROFILE_DEPENDENT); + + updateUpDownBtn(); + } + + + public void show() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.show(); + } + } + + public void hide() { + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.hide(); + } + } + +// private void updateAppearanceIcon() { +// Drawable icon = getTrackIcon(app, trackDrawInfo.getWidth(), trackDrawInfo.isShowArrows(), trackDrawInfo.getColor()); +// trackIcon.setImageDrawable(icon); +// } + + public static Drawable getTrackIcon(OsmandApplication app, String widthAttr, boolean showArrows, @ColorInt int color) { + int widthIconId = getWidthIconId(widthAttr); + Drawable widthIcon = app.getUIUtilities().getPaintedIcon(widthIconId, color); + + int strokeIconId = getStrokeIconId(widthAttr); + int strokeColor = UiUtilities.getColorWithAlpha(Color.BLACK, 0.7f); + Drawable strokeIcon = app.getUIUtilities().getPaintedIcon(strokeIconId, strokeColor); + + Drawable transparencyIcon = getTransparencyIcon(app, widthAttr, color); + if (showArrows) { + int arrowsIconId = getArrowsIconId(widthAttr); + int contrastColor = UiUtilities.getContrastColor(app, color, false); + Drawable arrows = app.getUIUtilities().getPaintedIcon(arrowsIconId, contrastColor); + return UiUtilities.getLayeredIcon(transparencyIcon, widthIcon, strokeIcon, arrows); + } + return UiUtilities.getLayeredIcon(transparencyIcon, widthIcon, strokeIcon); + } + + private static Drawable getTransparencyIcon(OsmandApplication app, String widthAttr, @ColorInt int color) { + int transparencyIconId = getTransparencyIconId(widthAttr); + int colorWithoutAlpha = UiUtilities.removeAlpha(color); + int transparencyColor = UiUtilities.getColorWithAlpha(colorWithoutAlpha, 0.8f); + return app.getUIUtilities().getPaintedIcon(transparencyIconId, transparencyColor); + } + + public static int getTransparencyIconId(String widthAttr) { + if (TRACK_WIDTH_BOLD.equals(widthAttr)) { + return R.drawable.ic_action_track_line_bold_transparency; + } else if (TRACK_WIDTH_MEDIUM.equals(widthAttr)) { + return R.drawable.ic_action_track_line_medium_transparency; + } else { + return R.drawable.ic_action_track_line_thin_transparency; + } + } + + public static int getArrowsIconId(String widthAttr) { + if (TRACK_WIDTH_BOLD.equals(widthAttr)) { + return R.drawable.ic_action_track_line_bold_direction; + } else if (TRACK_WIDTH_MEDIUM.equals(widthAttr)) { + return R.drawable.ic_action_track_line_medium_direction; + } else { + return R.drawable.ic_action_track_line_thin_direction; + } + } + + public static int getStrokeIconId(String widthAttr) { + if (TRACK_WIDTH_BOLD.equals(widthAttr)) { + return R.drawable.ic_action_track_line_bold_stroke; + } else if (TRACK_WIDTH_MEDIUM.equals(widthAttr)) { + return R.drawable.ic_action_track_line_medium_stroke; + } else { + return R.drawable.ic_action_track_line_thin_stroke; + } + } + + public static int getWidthIconId(String widthAttr) { + if (TRACK_WIDTH_BOLD.equals(widthAttr)) { + return R.drawable.ic_action_track_line_bold_color; + } else if (TRACK_WIDTH_MEDIUM.equals(widthAttr)) { + return R.drawable.ic_action_track_line_medium_color; + } else { + return R.drawable.ic_action_track_line_thin_color; + } + } + + private void setBackgroundAndPadding(boolean isChecked, int paddingSmall) { + if (nightMode) { + confirmEveryRun.setBackgroundResource( + isChecked ? R.drawable.layout_bg_dark_solid : R.drawable.layout_bg_dark); + } else { + confirmEveryRun.setBackgroundResource( + isChecked ? R.drawable.layout_bg_solid : R.drawable.layout_bg); + } + confirmEveryRun.setPadding(paddingSmall, 0, paddingSmall, 0); + } + + private void updateUpDownBtn() { + int iconId = infoExpanded ? R.drawable.ic_action_arrow_down : R.drawable.ic_action_arrow_up; + upDownBtn.setImageDrawable(getContentIcon(iconId)); + } + + private void toggleInfoView() { + infoExpanded = !infoExpanded; + AndroidUiHelper.updateVisibility(confirmEveryRun, infoExpanded); + updateUpDownBtn(); + } + + @Override + protected boolean useVerticalButtons() { + return true; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.start_recording; + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected DialogButtonType getRightBottomButtonType() { + return DialogButtonType.PRIMARY; + } + + @Override + public int getSecondDividerHeight() { + return getResources().getDimensionPixelSize(R.dimen.bottom_sheet_icon_margin); + } + + @Override + protected void onRightBottomButtonClick() { + app.getSavingTrackHelper().startNewSegment(); + settings.SAVE_GLOBAL_TRACK_TO_GPX.set(true); + app.startNavigationService(NavigationService.USED_BY_GPX); + dismiss(); + } + + @Nullable + public MapActivity getMapActivity() { + Activity activity = getActivity(); + if (activity instanceof MapActivity) { + return (MapActivity) activity; + } + return null; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager) { + if (!fragmentManager.isStateSaved() && fragmentManager.findFragmentByTag(TripRecordingBottomSheet.TAG) == null) { + TripRecordingBottomSheet fragment = new TripRecordingBottomSheet(); + fragment.show(fragmentManager, TAG); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 43642bfe9c..9a89f67017 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -42,6 +42,7 @@ import net.osmand.plus.dialogs.GpxAppearanceAdapter; import net.osmand.plus.dialogs.GpxAppearanceAdapter.AppearanceListItem; import net.osmand.plus.dialogs.GpxAppearanceAdapter.GpxAppearanceAdapterType; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.monitoring.TripRecordingBottomSheet; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; import net.osmand.plus.settings.backend.CommonPreference; @@ -160,8 +161,13 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement public void handleOnBackPressed() { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { + TripRecordingBottomSheet fragment = mapActivity.getTripRecordingBottomSheet(); + if (fragment != null) { + fragment.show(); + } else { + mapActivity.launchPrevActivityIntent(); + } dismissImmediate(); - mapActivity.launchPrevActivityIntent(); } } }); @@ -405,7 +411,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement } } - public Drawable getTrackIcon(OsmandApplication app, String widthAttr, boolean showArrows, @ColorInt int color) { + public static Drawable getTrackIcon(OsmandApplication app, String widthAttr, boolean showArrows, @ColorInt int color) { int widthIconId = getWidthIconId(widthAttr); Drawable widthIcon = app.getUIUtilities().getPaintedIcon(widthIconId, color); @@ -423,7 +429,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement return UiUtilities.getLayeredIcon(transparencyIcon, widthIcon, strokeIcon); } - private Drawable getTransparencyIcon(OsmandApplication app, String widthAttr, @ColorInt int color) { + private static Drawable getTransparencyIcon(OsmandApplication app, String widthAttr, @ColorInt int color) { int transparencyIconId = getTransparencyIconId(widthAttr); int colorWithoutAlpha = UiUtilities.removeAlpha(color); int transparencyColor = UiUtilities.getColorWithAlpha(colorWithoutAlpha, 0.8f); From 0e408dc4f3dd4c9fca48181e9ae8e2a6409e2496 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 18 Jan 2021 09:37:59 +0200 Subject: [PATCH 12/31] compound button --- .../net/osmand/plus/monitoring/TripRecordingBottomSheet.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 127729dc64..adfa686fce 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -151,8 +151,8 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { } boolean checked = !settings.SAVE_GLOBAL_TRACK_REMEMBER.get(); confirmEveryRun = itemView.findViewById(R.id.confirm_every_run); - confirmEveryRun.setBackgroundResource(nightMode ? R.drawable.layout_bg_dark : R.drawable.layout_bg); confirmEveryRun.setChecked(checked); + setBackgroundAndPadding(checked, paddingSmall); confirmEveryRun.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -160,8 +160,6 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment { settings.SAVE_GLOBAL_TRACK_REMEMBER.set(!isChecked); } }); - setBackgroundAndPadding(checked, paddingSmall); - UiUtilities.setupCompoundButton(confirmEveryRun, nightMode, PROFILE_DEPENDENT); SwitchCompat showTrackOnMapButton = showTrackOnMapView.findViewById(R.id.switch_button); showTrackOnMapButton.setChecked(app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null); From d0df11ed908b0a717efd26a497dbad60b7553b0b Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 18 Jan 2021 10:24:37 +0200 Subject: [PATCH 13/31] Small fixes in TripRecordingBottomSheet --- OsmAnd/res/layout/trip_recording_fragment.xml | 12 +- .../monitoring/TripRecordingBottomSheet.java | 130 +++++------------- 2 files changed, 36 insertions(+), 106 deletions(-) diff --git a/OsmAnd/res/layout/trip_recording_fragment.xml b/OsmAnd/res/layout/trip_recording_fragment.xml index d87a697a9d..a460193cd5 100644 --- a/OsmAnd/res/layout/trip_recording_fragment.xml +++ b/OsmAnd/res/layout/trip_recording_fragment.xml @@ -44,23 +44,13 @@ android:orientation="horizontal"> - - Date: Sun, 17 Jan 2021 10:52:02 +0200 Subject: [PATCH 14/31] crash fix --- .../net/osmand/plus/monitoring/OsmandMonitoringPlugin.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java index 4a496f6475..42bae2ab62 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/OsmandMonitoringPlugin.java @@ -505,8 +505,9 @@ public class OsmandMonitoringPlugin extends OsmandPlugin { }; if (choice.value || map == null) { runnable.run(); - } else { - TripRecordingBottomSheet.showInstance(mapActivity.getSupportFragmentManager()); + } else if (map instanceof FragmentActivity) { + FragmentActivity activity = (FragmentActivity) map; + TripRecordingBottomSheet.showInstance(activity.getSupportFragmentManager()); } } From f24ad18e5afa11d57f8b2c1dc82bd8767551aa73 Mon Sep 17 00:00:00 2001 From: Skalii Date: Sun, 17 Jan 2021 14:36:16 +0200 Subject: [PATCH 15/31] Show "Save/Cancel" buttons above keyboards; fix close keyboard on scrolling --- .../OnlineRoutingEngineFragment.java | 99 +++++++++++++++---- 1 file changed, 80 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index c34d6541a1..d0b8a4db7b 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -1,17 +1,21 @@ package net.osmand.plus.onlinerouting; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; +import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.ScrollView; import android.widget.TextView; import androidx.activity.OnBackPressedCallback; @@ -66,14 +70,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private View view; private ViewGroup segmentsContainer; - private ViewGroup scrollView; private OnlineRoutingCard nameCard; private OnlineRoutingCard typeCard; private OnlineRoutingCard vehicleCard; private OnlineRoutingCard apiKeyCard; private OnlineRoutingCard exampleCard; private View testResultsContainer; - private ViewTreeObserver.OnScrollChangedListener onScroll; + private ScrollView scrollView; + private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayout; + private boolean isKeyboardShown = false; private ApplicationMode appMode; @@ -146,6 +151,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { }); } + @SuppressLint("ClickableViewAccessibility") @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @@ -154,21 +160,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { view = getInflater().inflate( R.layout.online_routing_engine_fragment, container, false); segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); - scrollView = (ViewGroup) segmentsContainer.getParent(); - onScroll = new ViewTreeObserver.OnScrollChangedListener() { - int pastY = 0; - - @Override - public void onScrollChanged() { - int y = scrollView.getScrollY(); - if (pastY != y) { - pastY = y; - View focus = view.findFocus(); - AndroidUtils.hideSoftKeyboard(requireActivity(), focus); - } - } - }; - scrollView.getViewTreeObserver().addOnScrollChangedListener(onScroll); + scrollView = (ScrollView) segmentsContainer.getParent(); if (Build.VERSION.SDK_INT >= 21) { AndroidUtils.addStatusBarPadding21v(getContext(), view); } @@ -186,13 +178,82 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupButtons(); updateCardViews(nameCard, typeCard, vehicleCard, exampleCard); - return view; + + scrollView.setOnTouchListener(new View.OnTouchListener() { + int scrollViewY = 0; + @Override + public boolean onTouch(View v, MotionEvent event) { + int y = scrollView.getScrollY(); + if (isKeyboardShown && scrollViewY != y) { + scrollViewY = y; + View focus = getActivity().getCurrentFocus(); + if (focus != null) { + AndroidUtils.hideSoftKeyboard(requireActivity(), focus); + focus.clearFocus(); + } + } + return false; + } + }); + + onGlobalLayout = new ViewTreeObserver.OnGlobalLayoutListener() { + private int layoutHeightPrevious; + private int layoutHeightMin; + + @Override + public void onGlobalLayout() { + + final ViewTreeObserver.OnGlobalLayoutListener listener = this; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } + + Rect visibleDisplayFrame = new Rect(); + view.getWindowVisibleDisplayFrame(visibleDisplayFrame); + int layoutHeight = visibleDisplayFrame.bottom; + + if (layoutHeight < layoutHeightPrevious) { + isKeyboardShown = true; + layoutHeightMin = layoutHeight; + } else { + isKeyboardShown = layoutHeight == layoutHeightMin; + } + + if (layoutHeight != layoutHeightPrevious) { + FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams(); + rootViewLayout.height = layoutHeight; + view.requestLayout(); + layoutHeightPrevious = layoutHeight; + } + + view.post(new Runnable() { + @Override + public void run() { + view.getViewTreeObserver().addOnGlobalLayoutListener(listener); + } + }); + + } + }; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); + } + + return view; } @Override public void onDestroyView() { super.onDestroyView(); - scrollView.getViewTreeObserver().removeOnScrollChangedListener(onScroll); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); + } } private void setupNameCard() { From 128c08ca7f6e353c775f6224f3b262b18bdda915 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Sun, 17 Jan 2021 22:11:57 +0300 Subject: [PATCH 16/31] Introduced gms location service --- OsmAnd/build.gradle | 27 ++- .../plus/LocationServiceHelperImpl.java | 158 +++++++++++++ .../plus/LocationServiceHelperImpl.java | 188 ++++++++++++++++ .../net/osmand/plus/NavigationService.java | 70 +++--- .../osmand/plus/OsmAndLocationProvider.java | 213 ++++++------------ .../net/osmand/plus/OsmandApplication.java | 7 +- .../osmand/plus/helpers/DayNightHelper.java | 29 ++- .../plus/helpers/LocationServiceHelper.java | 29 +++ 8 files changed, 519 insertions(+), 202 deletions(-) create mode 100644 OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java create mode 100644 OsmAnd/src-nogms/net/osmand/plus/LocationServiceHelperImpl.java create mode 100644 OsmAnd/src/net/osmand/plus/helpers/LocationServiceHelper.java diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle index a3f80f4c46..24664da2a4 100644 --- a/OsmAnd/build.gradle +++ b/OsmAnd/build.gradle @@ -108,18 +108,25 @@ android { manifest.srcFile "AndroidManifest-debug.xml" } full { - java.srcDirs = ["src-google"] + java.srcDirs = ["src-nogms", "src-google"] + } + fullGms { + java.srcDirs = ["src-gms", "src-google"] } free { - java.srcDirs = ["src-google"] + java.srcDirs = ["src-nogms", "src-google"] + manifest.srcFile "AndroidManifest-free.xml" + } + freeGms { + java.srcDirs = ["src-gms", "src-google"] manifest.srcFile "AndroidManifest-free.xml" } freedev { - java.srcDirs = ["src-google"] + java.srcDirs = ["src-nogms", "src-google"] manifest.srcFile "AndroidManifest-freedev.xml" } freehuawei { - java.srcDirs = ["src-huawei"] + java.srcDirs = ["src-nogms", "src-google"] manifest.srcFile "AndroidManifest-freehuawei.xml" } @@ -172,10 +179,18 @@ android { dimension "version" applicationId "net.osmand" } + freeGms { + dimension "version" + applicationId "net.osmand" + } full { dimension "version" applicationId "net.osmand.plus" } + fullGms { + dimension "version" + applicationId "net.osmand.plus" + } freehuawei { dimension "version" applicationId "net.osmand.huawei" @@ -504,8 +519,10 @@ dependencies { exclude group: "com.fasterxml.jackson.core" } implementation 'com.jaredrummler:colorpicker:1.1.0' + implementation "org.bouncycastle:bcpkix-jdk15on:1.56" freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300' - implementation "org.bouncycastle:bcpkix-jdk15on:1.56" + freeGmsImplementation 'com.google.android.gms:play-services-location:17.1.0' + fullGmsImplementation 'com.google.android.gms:play-services-location:17.1.0' } diff --git a/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java new file mode 100644 index 0000000000..e8182955ec --- /dev/null +++ b/OsmAnd/src-gms/net/osmand/plus/LocationServiceHelperImpl.java @@ -0,0 +1,158 @@ +package net.osmand.plus; + +import android.location.Location; +import android.os.Looper; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationAvailability; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationResult; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.Tasks; + +import net.osmand.PlatformUtil; +import net.osmand.plus.helpers.DayNightHelper; +import net.osmand.plus.helpers.LocationServiceHelper; + +import org.apache.commons.logging.Log; + +import java.util.Collections; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class LocationServiceHelperImpl extends LocationServiceHelper { + + private static final Log LOG = PlatformUtil.getLog(DayNightHelper.class); + + private final OsmandApplication app; + + // FusedLocationProviderClient - Main class for receiving location updates. + private final FusedLocationProviderClient fusedLocationProviderClient; + + // LocationRequest - Requirements for the location updates, i.e., how often you should receive + // updates, the priority, etc. + private final LocationRequest fusedLocationRequest; + + // LocationCallback - Called when FusedLocationProviderClient has a new Location. + private final com.google.android.gms.location.LocationCallback fusedLocationCallback; + + private LocationCallback locationCallback; + + public LocationServiceHelperImpl(@NonNull OsmandApplication app) { + this.app = app; + + fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(app); + + fusedLocationRequest = new LocationRequest() + // Sets the desired interval for active location updates. This interval is inexact. You + // may not receive updates at all if no location sources are available, or you may + // receive them less frequently than requested. You may also receive updates more + // frequently than requested if other applications are requesting location at a more + // frequent interval. + // + // IMPORTANT NOTE: Apps running on Android 8.0 and higher devices (regardless of + // targetSdkVersion) may receive updates less frequently than this interval when the app + // is no longer in the foreground. + .setInterval(100) + + // Sets the fastest rate for active location updates. This interval is exact, and your + // application will never receive updates more frequently than this value. + .setFastestInterval(50) + + // Sets the maximum time when batched location updates are delivered. Updates may be + // delivered sooner than this interval. + .setMaxWaitTime(200) + + .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + + fusedLocationCallback = new com.google.android.gms.location.LocationCallback() { + @Override + public void onLocationResult(LocationResult locationResult) { + LocationCallback locationCallback = LocationServiceHelperImpl.this.locationCallback; + if (locationCallback != null) { + Location location = locationResult != null ? locationResult.getLastLocation() : null; + net.osmand.Location l = convertLocation(location); + locationCallback.onLocationResult(l == null + ? Collections.emptyList() : Collections.singletonList(l)); + } + + } + + @Override + public void onLocationAvailability(LocationAvailability locationAvailability) { + LocationCallback locationCallback = LocationServiceHelperImpl.this.locationCallback; + if (locationAvailability != null && locationCallback != null) { + locationCallback.onLocationAvailability(locationAvailability.isLocationAvailable()); + } + } + }; + } + + @Override + public void requestLocationUpdates(@NonNull LocationCallback locationCallback) { + this.locationCallback = locationCallback; + // request location updates + try { + fusedLocationProviderClient.requestLocationUpdates( + fusedLocationRequest, fusedLocationCallback, Looper.myLooper()); + } catch (SecurityException e) { + LOG.debug("Location service permission not granted"); + throw e; + } catch (IllegalArgumentException e) { + LOG.debug("GPS location provider not available"); + throw e; + } + } + + @Override + public boolean isNetworkLocationUpdatesSupported() { + return false; + } + + @Override + public void requestNetworkLocationUpdates(@NonNull LocationCallback locationCallback) { + } + + @Override + public void removeLocationUpdates() { + // remove location updates + try { + fusedLocationProviderClient.removeLocationUpdates(fusedLocationCallback); + } catch (SecurityException e) { + LOG.debug("Location service permission not granted", e); + throw e; + } + } + + @Nullable + public net.osmand.Location getFirstTimeRunDefaultLocation() { + final net.osmand.Location[] location = {null}; + /* + try { + Task lastLocation = fusedLocationProviderClient.getLastLocation(); + lastLocation.addOnSuccessListener(new OnSuccessListener() { + @Override + public void onSuccess(Location loc) { + location[0] = convertLocation(loc); + } + }); + } catch (SecurityException e) { + LOG.debug("Location service permission not granted"); + } catch (IllegalArgumentException e) { + LOG.debug("GPS location provider not available"); + } + */ + return location[0]; + } + + @Nullable + private net.osmand.Location convertLocation(@Nullable Location location) { + return location == null ? null : OsmAndLocationProvider.convertLocation(location, app); + } +} diff --git a/OsmAnd/src-nogms/net/osmand/plus/LocationServiceHelperImpl.java b/OsmAnd/src-nogms/net/osmand/plus/LocationServiceHelperImpl.java new file mode 100644 index 0000000000..5f49607954 --- /dev/null +++ b/OsmAnd/src-nogms/net/osmand/plus/LocationServiceHelperImpl.java @@ -0,0 +1,188 @@ +package net.osmand.plus; + +import android.content.Context; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.osmand.PlatformUtil; +import net.osmand.plus.helpers.DayNightHelper; +import net.osmand.plus.helpers.LocationServiceHelper; + +import org.apache.commons.logging.Log; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import static android.content.Context.LOCATION_SERVICE; + +public class LocationServiceHelperImpl extends LocationServiceHelper implements LocationListener { + + private static final Log LOG = PlatformUtil.getLog(DayNightHelper.class); + + private final OsmandApplication app; + + private LocationCallback locationCallback; + private LocationCallback networkLocationCallback; + private final LinkedList networkListeners = new LinkedList<>(); + + // Working with location checkListeners + private class NetworkListener implements LocationListener { + + @Override + public void onLocationChanged(Location location) { + LocationCallback locationCallback = LocationServiceHelperImpl.this.networkLocationCallback; + if (locationCallback != null) { + net.osmand.Location l = convertLocation(location); + locationCallback.onLocationResult(l == null + ? Collections.emptyList() : Collections.singletonList(l)); + } + } + + @Override + public void onProviderDisabled(String provider) { + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + } + + public LocationServiceHelperImpl(@NonNull OsmandApplication app) { + this.app = app; + } + + @Override + public void requestLocationUpdates(@NonNull LocationCallback locationCallback) { + this.locationCallback = locationCallback; + // request location updates + LocationManager locationManager = (LocationManager) app.getSystemService(LOCATION_SERVICE); + try { + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + } catch (SecurityException e) { + LOG.debug("Location service permission not granted"); + throw e; + } catch (IllegalArgumentException e) { + LOG.debug("GPS location provider not available"); + throw e; + } + } + + @Override + public boolean isNetworkLocationUpdatesSupported() { + return true; + } + + @Override + public void requestNetworkLocationUpdates(@NonNull LocationCallback locationCallback) { + this.networkLocationCallback = locationCallback; + // request location updates + LocationManager locationManager = (LocationManager) app.getSystemService(LOCATION_SERVICE); + List providers = locationManager.getProviders(true); + for (String provider : providers) { + if (provider == null || provider.equals(LocationManager.GPS_PROVIDER)) { + continue; + } + try { + NetworkListener networkListener = new NetworkListener(); + locationManager.requestLocationUpdates(provider, 0, 0, networkListener); + networkListeners.add(networkListener); + } catch (SecurityException e) { + LOG.debug(provider + " location service permission not granted"); + } catch (IllegalArgumentException e) { + LOG.debug(provider + " location provider not available"); + } + } + } + + @Override + public void removeLocationUpdates() { + // remove location updates + LocationManager locationManager = (LocationManager) app.getSystemService(LOCATION_SERVICE); + try { + locationManager.removeUpdates(this); + } catch (SecurityException e) { + LOG.debug("Location service permission not granted", e); + throw e; + } finally { + while (!networkListeners.isEmpty()) { + LocationListener listener = networkListeners.poll(); + if (listener != null) { + locationManager.removeUpdates(listener); + } + } + } + } + + @Nullable + public net.osmand.Location getFirstTimeRunDefaultLocation() { + LocationManager locationManager = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); + List providers = new ArrayList<>(locationManager.getProviders(true)); + // note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it. + // constant should not be changed in future + int passiveFirst = providers.indexOf(LocationManager.PASSIVE_PROVIDER); + // put passive provider to first place + if (passiveFirst > -1) { + providers.add(0, providers.remove(passiveFirst)); + } + // find location + for (String provider : providers) { + try { + net.osmand.Location location = convertLocation(locationManager.getLastKnownLocation(provider)); + if (location != null) { + return location; + } + } catch (SecurityException e) { + // location service permission not granted + } catch (IllegalArgumentException e) { + // location provider not available + } + } + return null; + } + + @Nullable + private net.osmand.Location convertLocation(@Nullable Location location) { + return location == null ? null : OsmAndLocationProvider.convertLocation(location, app); + } + + @Override + public void onLocationChanged(Location location) { + LocationCallback locationCallback = this.locationCallback; + if (locationCallback != null) { + net.osmand.Location l = convertLocation(location); + locationCallback.onLocationResult(l == null + ? Collections.emptyList() : Collections.singletonList(l)); + } + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + @Override + public void onProviderEnabled(String provider) { + LocationCallback locationCallback = this.locationCallback; + if (locationCallback != null) { + locationCallback.onLocationAvailability(true); + } + } + + @Override + public void onProviderDisabled(String provider) { + LocationCallback locationCallback = this.locationCallback; + if (locationCallback != null) { + locationCallback.onLocationAvailability(false); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index 3a824f937e..16f1afddcc 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -4,20 +4,24 @@ import android.app.Notification; import android.app.Service; import android.content.Context; import android.content.Intent; -import android.location.Location; -import android.location.LocationListener; import android.location.LocationManager; import android.os.Binder; -import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.widget.Toast; +import androidx.annotation.NonNull; + +import net.osmand.Location; import net.osmand.PlatformUtil; +import net.osmand.plus.helpers.LocationServiceHelper; +import net.osmand.plus.helpers.LocationServiceHelper.LocationCallback; import net.osmand.plus.notifications.OsmandNotification; import net.osmand.plus.settings.backend.OsmandSettings; -public class NavigationService extends Service implements LocationListener { +import java.util.List; + +public class NavigationService extends Service { public static class NavigationServiceBinder extends Binder { } @@ -29,11 +33,11 @@ public class NavigationService extends Service implements LocationListener { private final NavigationServiceBinder binder = new NavigationServiceBinder(); - private String serviceOffProvider; private OsmandSettings settings; protected int usedBy = 0; private OsmAndLocationProvider locationProvider; + private LocationServiceHelper locationServiceHelper; @Override public IBinder onBind(Intent intent) { @@ -72,21 +76,37 @@ public class NavigationService extends Service implements LocationListener { settings = app.getSettings(); usedBy = intent.getIntExtra(USAGE_INTENT, 0); - // use only gps provider - serviceOffProvider = LocationManager.GPS_PROVIDER; locationProvider = app.getLocationProvider(); + locationServiceHelper = app.createLocationServiceHelper(); app.setNavigationService(this); // request location updates - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); try { - locationManager.requestLocationUpdates(serviceOffProvider, 0, 0, NavigationService.this); + locationServiceHelper.requestLocationUpdates(new LocationCallback() { + @Override + public void onLocationResult(@NonNull List locations) { + if (!locations.isEmpty()) { + Location location = locations.get(locations.size() - 1); + if (!settings.MAP_ACTIVITY_ENABLED.get()) { + locationProvider.setLocationFromService(location); + } + } + } + + @Override + public void onLocationAvailability(boolean locationAvailable) { + if (!locationAvailable) { + OsmandApplication app = (OsmandApplication) getApplication(); + if (app != null) { + app.showToastMessage(getString(R.string.off_router_service_no_gps_available)); + } + } + } + }); } catch (SecurityException e) { Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show(); - Log.d(PlatformUtil.TAG, "Location service permission not granted"); //$NON-NLS-1$ } catch (IllegalArgumentException e) { Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show(); - Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$ } // registering icon at top level @@ -117,11 +137,10 @@ public class NavigationService extends Service implements LocationListener { app.setNavigationService(null); usedBy = 0; // remove updates - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); try { - locationManager.removeUpdates(this); + locationServiceHelper.removeLocationUpdates(); } catch (SecurityException e) { - Log.d(PlatformUtil.TAG, "Location service permission not granted"); //$NON-NLS-1$ + // Location service permission not granted } // remove notification stopForeground(Boolean.TRUE); @@ -134,29 +153,6 @@ public class NavigationService extends Service implements LocationListener { }, 500); } - @Override - public void onLocationChanged(Location l) { - if (l != null && !settings.MAP_ACTIVITY_ENABLED.get()) { - net.osmand.Location location = OsmAndLocationProvider.convertLocation(l, (OsmandApplication) getApplication()); - locationProvider.setLocationFromService(location); - } - } - - @Override - public void onProviderDisabled(String provider) { - Toast.makeText(this, getString(R.string.off_router_service_no_gps_available), Toast.LENGTH_LONG).show(); - } - - - @Override - public void onProviderEnabled(String provider) { - } - - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - } - @Override public void onTaskRemoved(Intent rootIntent) { OsmandApplication app = ((OsmandApplication) getApplication()); diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index a19ebd3023..ee875fbb17 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -1,6 +1,7 @@ package net.osmand.plus; import android.Manifest; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; @@ -16,7 +17,6 @@ import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.GpsStatus.Listener; import android.location.Location; -import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.Build.VERSION; @@ -25,6 +25,7 @@ import android.os.Bundle; import android.provider.Settings; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; @@ -38,8 +39,9 @@ import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.data.QuadPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint; -import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.helpers.LocationServiceHelper; import net.osmand.plus.routing.RouteSegmentSearchResult; +import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.router.RouteSegmentResult; @@ -47,8 +49,6 @@ import net.osmand.util.MapUtils; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -75,8 +75,6 @@ public class OsmAndLocationProvider implements SensorEventListener { private static final float ACCURACY_FOR_GPX_AND_ROUTING = 50; - private static final int GPS_TIMEOUT_REQUEST = 0; - private static final int GPS_DIST_REQUEST = 0; private static final int NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS = 12000; private static final long LOCATION_TIMEOUT_TO_BE_STALE = 1000 * 60 * 2; // 2 minutes @@ -85,9 +83,8 @@ public class OsmAndLocationProvider implements SensorEventListener { private static final long AGPS_TO_REDOWNLOAD = 16 * 60 * 60 * 1000; // 16 hours private static final int REQUESTS_BEFORE_CHECK_LOCATION = 100; - private AtomicInteger locationRequestsCounter = new AtomicInteger(); - private AtomicInteger staleLocationRequestsCounter = new AtomicInteger(); - + private final AtomicInteger locationRequestsCounter = new AtomicInteger(); + private final AtomicInteger staleLocationRequestsCounter = new AtomicInteger(); private long lastTimeGPSLocationFixed = 0; @@ -121,23 +118,23 @@ public class OsmAndLocationProvider implements SensorEventListener { // Current screen orientation private int currentScreenOrientation; - private OsmandApplication app; + private final OsmandApplication app; - private NavigationInfo navigationInfo; - private CurrentPositionHelper currentPositionHelper; - private OsmAndLocationSimulation locationSimulation; + private final NavigationInfo navigationInfo; + private final CurrentPositionHelper currentPositionHelper; + private final OsmAndLocationSimulation locationSimulation; + private final LocationServiceHelper locationServiceHelper; private net.osmand.Location location = null; private GPSInfo gpsInfo = new GPSInfo(); - private List locationListeners = new ArrayList(); - private List compassListeners = new ArrayList(); + private List locationListeners = new ArrayList<>(); + private List compassListeners = new ArrayList<>(); private Object gpsStatusListener; private float[] mRotationM = new float[9]; - - public class SimulationProvider { + public static class SimulationProvider { private int currentRoad; private int currentSegment; private QuadPoint currentPoint; @@ -227,6 +224,7 @@ public class OsmAndLocationProvider implements SensorEventListener { navigationInfo = new NavigationInfo(app); currentPositionHelper = new CurrentPositionHelper(app); locationSimulation = new OsmAndLocationSimulation(app, this); + locationServiceHelper = app.createLocationServiceHelper(); addLocationListener(navigationInfo); addCompassListener(navigationInfo); } @@ -235,7 +233,7 @@ public class OsmAndLocationProvider implements SensorEventListener { final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); if (app.getSettings().isInternetConnectionAvailable()) { if (System.currentTimeMillis() - app.getSettings().AGPS_DATA_LAST_TIME_DOWNLOADED.get() > AGPS_TO_REDOWNLOAD) { - //force an updated check for internet connectivity here before destroying A-GPS-data + // force an updated check for internet connectivity here before destroying A-GPS-data if (app.getSettings().isInternetConnectionAvailable(true)) { redownloadAGPS(); } @@ -244,27 +242,34 @@ public class OsmAndLocationProvider implements SensorEventListener { if (isLocationPermissionAvailable(app)) { registerGpsStatusListener(service); try { - service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener); + locationServiceHelper.requestLocationUpdates(new LocationServiceHelper.LocationCallback() { + @Override + public void onLocationResult(@NonNull List locations) { + net.osmand.Location location = null; + if (!locations.isEmpty()) { + location = locations.get(locations.size() - 1); + lastTimeGPSLocationFixed = System.currentTimeMillis(); + } + if (!locationSimulation.isRouteAnimating()) { + setLocation(location); + } + } + }); + } catch (SecurityException e) { + // Location service permission not granted } catch (IllegalArgumentException e) { - Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$ + // GPS location provider not available } // try to always ask for network provide : it is faster way to find location - - List providers = service.getProviders(true); - if (providers == null) { - return; - } - for (String provider : providers) { - if (provider == null || provider.equals(LocationManager.GPS_PROVIDER)) { - continue; - } - try { - NetworkListener networkListener = new NetworkListener(); - service.requestLocationUpdates(provider, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener); - networkListeners.add(networkListener); - } catch (IllegalArgumentException e) { - Log.d(PlatformUtil.TAG, provider + " location provider not available"); //$NON-NLS-1$ - } + if (locationServiceHelper.isNetworkLocationUpdatesSupported()) { + locationServiceHelper.requestNetworkLocationUpdates(new LocationServiceHelper.LocationCallback() { + @Override + public void onLocationResult(@NonNull List locations) { + if (!locations.isEmpty() && !useOnlyGPS() && !locationSimulation.isRouteAnimating()) { + setLocation(locations.get(locations.size() - 1)); + } + } + }); } } } @@ -284,8 +289,9 @@ public class OsmAndLocationProvider implements SensorEventListener { } } - private void registerGpsStatusListener(final LocationManager service) { - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + @SuppressLint("MissingPermission") + private void registerGpsStatusListener(@NonNull final LocationManager service) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { gpsStatusListener = new GnssStatus.Callback() { @Override @@ -320,7 +326,7 @@ public class OsmAndLocationProvider implements SensorEventListener { updateLocation(location); } }; - service.registerGnssStatusCallback((GnssStatus.Callback) gpsStatusListener); + service.registerGnssStatusCallback((GnssStatus.Callback) gpsStatusListener, null); } else { gpsStatusListener = new Listener() { private GpsStatus gpsStatus; @@ -335,14 +341,12 @@ public class OsmAndLocationProvider implements SensorEventListener { } } - private void updateGPSInfo(GpsStatus s) { + private void updateGPSInfo(@Nullable GpsStatus s) { boolean fixed = false; int n = 0; int u = 0; if (s != null) { - Iterator iterator = s.getSatellites().iterator(); - while (iterator.hasNext()) { - GpsSatellite g = iterator.next(); + for (GpsSatellite g : s.getSatellites()) { n++; if (g.usedInFix()) { u++; @@ -354,7 +358,8 @@ public class OsmAndLocationProvider implements SensorEventListener { gpsInfo.foundSatellites = n; gpsInfo.usedSatellites = u; } - + + @NonNull public GPSInfo getGPSInfo(){ return gpsInfo; } @@ -363,51 +368,29 @@ public class OsmAndLocationProvider implements SensorEventListener { currentScreenOrientation = orientation; } - public void addLocationListener(OsmAndLocationListener listener){ - if(!locationListeners.contains(listener)) { + public void addLocationListener(@NonNull OsmAndLocationListener listener) { + if (!locationListeners.contains(listener)) { locationListeners.add(listener); } } - public void removeLocationListener(OsmAndLocationListener listener){ + public void removeLocationListener(@NonNull OsmAndLocationListener listener) { locationListeners.remove(listener); } - public void addCompassListener(OsmAndCompassListener listener){ - if(!compassListeners.contains(listener)) { + public void addCompassListener(@NonNull OsmAndCompassListener listener) { + if (!compassListeners.contains(listener)) { compassListeners.add(listener); } } - public void removeCompassListener(OsmAndCompassListener listener){ + public void removeCompassListener(@NonNull OsmAndCompassListener listener) { compassListeners.remove(listener); } + @Nullable public net.osmand.Location getFirstTimeRunDefaultLocation() { - if (!isLocationPermissionAvailable(app)) { - return null; - } - LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); - List ps = service.getProviders(true); - if(ps == null) { - return null; - } - List providers = new ArrayList(ps); - // note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it. - // constant should not be changed in future - int passiveFirst = providers.indexOf("passive"); // LocationManager.PASSIVE_PROVIDER - // put passive provider to first place - if (passiveFirst > -1) { - providers.add(0, providers.remove(passiveFirst)); - } - // find location - for (String provider : providers) { - net.osmand.Location location = convertLocation(service.getLastKnownLocation(provider), app); - if (location != null) { - return location; - } - } - return null; + return isLocationPermissionAvailable(app) ? locationServiceHelper.getFirstTimeRunDefaultLocation() : null; } public synchronized void registerOrUnregisterCompassListener(boolean register) { @@ -466,10 +449,7 @@ public class OsmAndLocationProvider implements SensorEventListener { } private boolean isRunningOnEmulator() { - if (Build.DEVICE.equals("generic")) { //$NON-NLS-1$ - return true; - } - return false; + return Build.DEVICE.equals("generic"); } @Override @@ -599,78 +579,25 @@ public class OsmAndLocationProvider implements SensorEventListener { return MapUtils.unifyRotationTo360((float) (Math.atan2(sinA, cosA) * 180 / Math.PI)); } - private void updateLocation(net.osmand.Location loc) { for (OsmAndLocationListener l : locationListeners) { l.updateLocation(loc); } } - - - private LocationListener gpsListener = new LocationListener() { - @Override - public void onLocationChanged(Location location) { - if (location != null) { - // lastTimeGPSLocationFixed = location.getTime(); - lastTimeGPSLocationFixed = System.currentTimeMillis(); - } - if(!locationSimulation.isRouteAnimating()) { - setLocation(convertLocation(location, app)); - } - } - - @Override - public void onProviderDisabled(String provider) { - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - } - }; - private LinkedList networkListeners = new LinkedList(); - private boolean useOnlyGPS() { - if(app.getRoutingHelper().isFollowingMode()) { + if (app.getRoutingHelper().isFollowingMode()) { return true; } - if((System.currentTimeMillis() - lastTimeGPSLocationFixed) < NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS) { + if ((System.currentTimeMillis() - lastTimeGPSLocationFixed) < NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS) { return true; } - if(isRunningOnEmulator()) { + if (isRunningOnEmulator()) { return true; } return false; } - // Working with location checkListeners - private class NetworkListener implements LocationListener { - - @Override - public void onLocationChanged(Location location) { - if (!useOnlyGPS() && !locationSimulation.isRouteAnimating()) { - setLocation(convertLocation(location, app)); - } - } - - @Override - public void onProviderDisabled(String provider) { - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - } - - }; - private void stopLocationRequests() { LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); if (gpsStatusListener != null) { @@ -680,9 +607,10 @@ public class OsmAndLocationProvider implements SensorEventListener { service.removeGpsStatusListener((Listener) gpsStatusListener); } } - service.removeUpdates(gpsListener); - while (!networkListeners.isEmpty()) { - service.removeUpdates(networkListeners.poll()); + try { + locationServiceHelper.removeLocationUpdates(); + } catch (SecurityException e) { + // Location service permission not granted } } @@ -963,7 +891,7 @@ public class OsmAndLocationProvider implements SensorEventListener { } public static boolean isNotSimulatedLocation(net.osmand.Location l) { - if(l != null) { + if (l != null) { return !SIMULATED_PROVIDER.equals(l.getProvider()); } return true; @@ -984,7 +912,7 @@ public class OsmAndLocationProvider implements SensorEventListener { networkenabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch(Exception ex) {} - if(!gpsenabled && !networkenabled) { + if (!gpsenabled && !networkenabled) { // notify user AlertDialog.Builder dialog = new AlertDialog.Builder(context); dialog.setMessage(context.getResources().getString(R.string.gps_network_not_enabled)); @@ -1003,11 +931,8 @@ public class OsmAndLocationProvider implements SensorEventListener { } public static boolean isLocationPermissionAvailable(Context context) { - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED) { - return false; - } - return true; + return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED; } public static void requestFineLocationPermissionIfNeeded(Activity activity) { diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 8deb9c81a8..842a36237e 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -57,6 +57,7 @@ import net.osmand.plus.download.DownloadService; import net.osmand.plus.download.IndexItem; import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.DayNightHelper; +import net.osmand.plus.helpers.LocationServiceHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.enums.DrivingRegion; @@ -300,7 +301,11 @@ public class OsmandApplication extends MultiDexApplication { public QuickActionRegistry getQuickActionRegistry() { return quickActionRegistry; } - + + public LocationServiceHelper createLocationServiceHelper() { + return new LocationServiceHelperImpl(this); + } + public void setAppCustomization(OsmAndAppCustomization appCustomization) { this.appCustomization = appCustomization; this.appCustomization.setup(this); diff --git a/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java index d3ebe9d6ae..20820d379e 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/DayNightHelper.java @@ -43,10 +43,10 @@ public class DayNightHelper implements SensorEventListener { private static final Log log = PlatformUtil.getLog(DayNightHelper.class); - private final OsmandApplication osmandApplication; + private final OsmandApplication app; - public DayNightHelper(OsmandApplication osmandApplication) { - this.osmandApplication = osmandApplication; + public DayNightHelper(OsmandApplication app) { + this.app = app; } private DayNightHelper listener; @@ -56,11 +56,11 @@ public class DayNightHelper implements SensorEventListener { private StateChangedListener sensorStateListener; public boolean isNightModeForMapControls() { - return isNightModeForMapControlsForProfile(osmandApplication.getSettings().APPLICATION_MODE.get()); + return isNightModeForMapControlsForProfile(app.getSettings().APPLICATION_MODE.get()); } public boolean isNightModeForMapControlsForProfile(ApplicationMode mode) { - if (osmandApplication.getSettings().isLightContentForMode(mode)) { + if (app.getSettings().isLightContentForMode(mode)) { return isNightModeForProfile(mode); } else { return true; @@ -72,11 +72,11 @@ public class DayNightHelper implements SensorEventListener { * @return true if day is supposed to be */ public boolean isNightMode() { - return isNightModeForProfile(osmandApplication.getSettings().APPLICATION_MODE.get()); + return isNightModeForProfile(app.getSettings().APPLICATION_MODE.get()); } public boolean isNightModeForProfile(ApplicationMode mode) { - DayNightMode dayNightMode = osmandApplication.getSettings().DAYNIGHT_MODE.getModeValue(mode); + DayNightMode dayNightMode = app.getSettings().DAYNIGHT_MODE.getModeValue(mode); if (dayNightMode.isDay()) { return false; } else if (dayNightMode.isNight()) { @@ -108,24 +108,23 @@ public class DayNightHelper implements SensorEventListener { } public SunriseSunset getSunriseSunset() { - Location lastKnownLocation = osmandApplication.getLocationProvider().getLastKnownLocation(); - if(lastKnownLocation == null) { - lastKnownLocation = osmandApplication.getLocationProvider().getFirstTimeRunDefaultLocation(); + Location lastKnownLocation = app.getLocationProvider().getLastKnownLocation(); + if (lastKnownLocation == null) { + lastKnownLocation = app.getLocationProvider().getFirstTimeRunDefaultLocation(); } if (lastKnownLocation == null) { return null; } double longitude = lastKnownLocation.getLongitude(); Date actualTime = new Date(); - SunriseSunset daynightSwitch = new SunriseSunset(lastKnownLocation.getLatitude(), + return new SunriseSunset(lastKnownLocation.getLatitude(), longitude < 0 ? 360 + longitude : longitude, actualTime, TimeZone.getDefault()); - return daynightSwitch; } public void stopSensorIfNeeded() { if (listener != null) { - SensorManager mSensorManager = (SensorManager) osmandApplication + SensorManager mSensorManager = (SensorManager) app .getSystemService(Context.SENSOR_SERVICE); Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); mSensorManager.unregisterListener(listener, mLight); @@ -135,9 +134,9 @@ public class DayNightHelper implements SensorEventListener { public void startSensorIfNeeded(StateChangedListener sensorStateListener) { this.sensorStateListener = sensorStateListener; - DayNightMode dayNightMode = osmandApplication.getSettings().DAYNIGHT_MODE.get(); + DayNightMode dayNightMode = app.getSettings().DAYNIGHT_MODE.get(); if (listener == null && dayNightMode.isSensor()) { - SensorManager mSensorManager = (SensorManager) osmandApplication.getSystemService(Context.SENSOR_SERVICE); + SensorManager mSensorManager = (SensorManager) app.getSystemService(Context.SENSOR_SERVICE); Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); List list = mSensorManager.getSensorList(Sensor.TYPE_LIGHT); log.info("Light sensors:" + list.size()); //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/plus/helpers/LocationServiceHelper.java b/OsmAnd/src/net/osmand/plus/helpers/LocationServiceHelper.java new file mode 100644 index 0000000000..94602e98fc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/helpers/LocationServiceHelper.java @@ -0,0 +1,29 @@ +package net.osmand.plus.helpers; + +import androidx.annotation.NonNull; + +import net.osmand.Location; + +import java.util.List; + +public abstract class LocationServiceHelper { + + public static abstract class LocationCallback { + + public void onLocationResult(@NonNull List locations) { + } + + public void onLocationAvailability(boolean locationAvailable) { + } + } + + public abstract void requestLocationUpdates(@NonNull LocationCallback locationCallback); + + public abstract boolean isNetworkLocationUpdatesSupported(); + + public abstract void requestNetworkLocationUpdates(@NonNull LocationCallback locationCallback); + + public abstract void removeLocationUpdates(); + + public abstract Location getFirstTimeRunDefaultLocation(); +} From a6adf50553eda6ce107cf28a7266970384961bef Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 17 Jan 2021 21:24:12 +0200 Subject: [PATCH 17/31] Lefthand routes are not shown correctly in automatic mode --- .../src/net/osmand/plus/TargetPointsHelper.java | 2 +- .../net/osmand/plus/activities/MapActivity.java | 1 + .../plus/base/MapViewTrackingUtilities.java | 16 +++++++++++++--- .../net/osmand/plus/routing/RoutingHelper.java | 2 +- .../osmand/plus/routing/RoutingHelperUtils.java | 12 +++++------- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java b/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java index 63d82ecc26..472899862b 100644 --- a/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java +++ b/OsmAnd/src/net/osmand/plus/TargetPointsHelper.java @@ -445,7 +445,7 @@ public class TargetPointsHelper { Location lastKnownLocation = ctx.getLocationProvider().getLastKnownLocation(); LatLon latLon = lastKnownLocation != null ? new LatLon(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()) : null; - RoutingHelperUtils.checkAndUpdateStartLocation(ctx, latLon); + RoutingHelperUtils.checkAndUpdateStartLocation(ctx, latLon, false); setMyLocationPoint(latLon, false, null); } } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 10fa1a066b..0f27fc6e26 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1408,6 +1408,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven updateMapSettings(); app.getPoiFilters().loadSelectedPoiFilters(); mapViewTrackingUtilities.updateSettings(); + mapViewTrackingUtilities.resetDrivingRegionUpdate(); //app.getRoutingHelper().setAppMode(settings.getApplicationMode()); if (mapLayers.getMapInfoLayer() != null) { mapLayers.getMapInfoLayer().recreateControls(); diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index fa66a5c91a..14a6623eae 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -13,8 +13,6 @@ import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.map.IMapLocationListener; import net.osmand.map.WorldRegion; -import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.OsmAndConstants; import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; @@ -22,10 +20,14 @@ import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.dashboard.DashboardOnMap; +import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; +import net.osmand.plus.mapmarkers.MapMarker; +import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelperUtils; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.OsmandMapTileView; @@ -176,7 +178,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc locationProvider = location.getProvider(); if (settings.DRIVING_REGION_AUTOMATIC.get() && !drivingRegionUpdated && !app.isApplicationInitializing()) { drivingRegionUpdated = true; - RoutingHelperUtils.checkAndUpdateStartLocation(app, location); + RoutingHelperUtils.checkAndUpdateStartLocation(app, location, true); } } if (mapView != null) { @@ -489,7 +491,15 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc @Override protected void onPostExecute(WorldRegion worldRegion) { if (worldRegion != null) { + DrivingRegion oldRegion = app.getSettings().DRIVING_REGION.get(); + app.setupDrivingRegion(worldRegion); + + DrivingRegion currentRegion = app.getSettings().DRIVING_REGION.get(); + if (oldRegion.leftHandDriving != currentRegion.leftHandDriving) { + ApplicationMode mode = app.getRoutingHelper().getAppMode(); + app.getRoutingHelper().onSettingsChanged(mode, true); + } } } } diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 03af123cc8..1addb2f50a 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -194,7 +194,7 @@ public class RoutingHelper { } public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List intermediatePoints, Location currentLocation) { - RoutingHelperUtils.checkAndUpdateStartLocation(app, currentLocation); + RoutingHelperUtils.checkAndUpdateStartLocation(app, currentLocation, false); RouteCalculationResult previousRoute = route; clearCurrentRoute(finalLocation, intermediatePoints); // to update route diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java index b756238eca..6803a2920f 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelperUtils.java @@ -8,9 +8,6 @@ import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.plus.OsmandApplication; import net.osmand.plus.TargetPointsHelper; -import net.osmand.plus.helpers.enums.MetricsConstants; -import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.MapUtils; import java.util.List; @@ -164,19 +161,20 @@ public class RoutingHelperUtils { } - public static void checkAndUpdateStartLocation(@NonNull OsmandApplication app, LatLon newStartLocation) { + public static void checkAndUpdateStartLocation(@NonNull OsmandApplication app, LatLon newStartLocation, boolean force) { if (newStartLocation != null) { LatLon lastStartLocation = app.getSettings().getLastStartPoint(); - if (lastStartLocation == null || MapUtils.getDistance(newStartLocation, lastStartLocation) > CACHE_RADIUS) { + if (lastStartLocation == null || MapUtils.getDistance(newStartLocation, lastStartLocation) > CACHE_RADIUS || force) { app.getMapViewTrackingUtilities().detectDrivingRegion(newStartLocation); app.getSettings().setLastStartPoint(newStartLocation); } } } - public static void checkAndUpdateStartLocation(@NonNull OsmandApplication app, Location nextStartLocation) { + public static void checkAndUpdateStartLocation(@NonNull OsmandApplication app, Location nextStartLocation, boolean force) { if (nextStartLocation != null) { - checkAndUpdateStartLocation(app, new LatLon(nextStartLocation.getLatitude(), nextStartLocation.getLongitude())); + LatLon newStartLocation = new LatLon(nextStartLocation.getLatitude(), nextStartLocation.getLongitude()); + checkAndUpdateStartLocation(app, newStartLocation, force); } } } From cb1f203cc121cee423794d18f4cb59e4fa4fa40b Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 18 Jan 2021 01:09:45 +0200 Subject: [PATCH 18/31] Implement Online routing backend (fixes after code review) --- OsmAnd/res/values-ar/strings.xml | 1 - OsmAnd/res/values-cs/strings.xml | 1 - OsmAnd/res/values-de/strings.xml | 1 - OsmAnd/res/values-eo/strings.xml | 1 - OsmAnd/res/values-es-rAR/strings.xml | 1 - OsmAnd/res/values-eu/strings.xml | 1 - OsmAnd/res/values-fa/strings.xml | 1 - OsmAnd/res/values-fr/strings.xml | 1 - OsmAnd/res/values-gl/strings.xml | 1 - OsmAnd/res/values-hu/strings.xml | 1 - OsmAnd/res/values-is/strings.xml | 1 - OsmAnd/res/values-iw/strings.xml | 1 - OsmAnd/res/values-ka/strings.xml | 1 - OsmAnd/res/values-lt/strings.xml | 1 - OsmAnd/res/values-nl/strings.xml | 1 - OsmAnd/res/values-pl/strings.xml | 1 - OsmAnd/res/values-pt-rBR/strings.xml | 1 - OsmAnd/res/values-sc/strings.xml | 1 - OsmAnd/res/values-sk/strings.xml | 1 - OsmAnd/res/values-tr/strings.xml | 1 - OsmAnd/res/values-uk/strings.xml | 1 - OsmAnd/res/values-zh-rTW/strings.xml | 1 - OsmAnd/res/values/strings.xml | 16 +++++++++++++++- .../plus/onlinerouting/OnlineRoutingHelper.java | 2 +- .../onlinerouting/engine/GraphhopperEngine.java | 6 ++++-- .../engine/OnlineRoutingEngine.java | 14 ++++++-------- .../plus/onlinerouting/engine/OrsEngine.java | 2 ++ .../plus/onlinerouting/engine/OsrmEngine.java | 2 ++ .../plus/onlinerouting/ui/OnlineRoutingCard.java | 2 +- .../profiles/OnlineRoutingEngineDataObject.java | 8 ++++---- .../backup/OnlineRoutingSettingsItem.java | 2 +- 31 files changed, 36 insertions(+), 40 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index bd3397afc2..4a9fde833f 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4023,7 +4023,6 @@ قدم دراجة هوائية سيارة - خطأ، أعد التحقق من المعايير نسخ العنوان محرك التوجيه عبر الإنترنت محركات التوجيه عبر الإنترنت diff --git a/OsmAnd/res/values-cs/strings.xml b/OsmAnd/res/values-cs/strings.xml index 38af3fcceb..6d6b906b06 100644 --- a/OsmAnd/res/values-cs/strings.xml +++ b/OsmAnd/res/values-cs/strings.xml @@ -3960,7 +3960,6 @@ Chůze Kolo Auto - Chyba, zkontrolujte parametry Kopírovat adresu Online navigační služba Online navigační služby diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index e66df6bcd7..b216a47c7c 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -3962,7 +3962,6 @@ Zu Fuß Fahrrad Auto - Fehler, Parameter erneut prüfen Subtyp Leer lassen, wenn kein API-Schlüssel vorhanden Adresse kopieren diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 391e96ba42..9671d14e5f 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -3960,7 +3960,6 @@ Piediranto Biciklo Aŭtomobilo - Eraro, rekontrolu parametrojn Kopii adreson Enreta navigilo Enretaj navigiloj diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index fd54cd500f..83700ce7cd 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -3963,7 +3963,6 @@ Peatón Bicicleta Automóvil - Error, vuelve a comprobar los parámetros Copiar dirección Motor de navegación en línea Motores de navegación en línea diff --git a/OsmAnd/res/values-eu/strings.xml b/OsmAnd/res/values-eu/strings.xml index ee2a825985..dced5cf049 100644 --- a/OsmAnd/res/values-eu/strings.xml +++ b/OsmAnd/res/values-eu/strings.xml @@ -3933,6 +3933,5 @@ Area honi dagokio: %1$s x %2$s Oinez Bizikleta Kotxea - Errorea, egiaztatu parametroak berriro Kopiatu helbidea \ No newline at end of file diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index 3cb0760eac..226a00cc5c 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -3953,5 +3953,4 @@ پا دوچرخه خودرو - خطا، پارامترها را بازبینی کنید \ No newline at end of file diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 0b7dc82b1c..e5f41539c2 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3947,7 +3947,6 @@ A pieds Vélo Automobile - Erreur, vérifiez les paramètres Ajouter un moteur de routage en ligne Modifier le moteur de routage en ligne L\'URL avec tous les paramètres sera de la forme : diff --git a/OsmAnd/res/values-gl/strings.xml b/OsmAnd/res/values-gl/strings.xml index 2e0c0053d3..5570577760 100644 --- a/OsmAnd/res/values-gl/strings.xml +++ b/OsmAnd/res/values-gl/strings.xml @@ -3968,7 +3968,6 @@ Lon %2$s Bicicleta Coche - Erro, verifica novamente os parámetros Copiar enderezo Horarios dos avisos por voz Motor de navegación en liña diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index d893dcf47e..64d40e287c 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -3954,7 +3954,6 @@ Hagyja üresen, ha nem Az összes paraméterrel rendelkező URL így néz ki: Útvonaltervezés kipróbálása - Hiba, ellenőrizze újra a paramétereket Cím másolása Online útvonaltervező Online útvonaltervezők diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index 3449458457..0b94e361f7 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -3965,6 +3965,5 @@ Gangandi Hjólandi Bíll - Villa, yfirfarðu breytur Afrita heimilisfang \ No newline at end of file diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 44f2c8c034..7ca3bcdb8d 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -3963,7 +3963,6 @@ ברגל אופנוע מכונית - שגיאה, נא לבדוק את המשתנים מחדש העתקת כתובת מנוע ניווט מקוון מנועי ניווט מקוונים diff --git a/OsmAnd/res/values-ka/strings.xml b/OsmAnd/res/values-ka/strings.xml index 770916e3b3..330d43d2c4 100644 --- a/OsmAnd/res/values-ka/strings.xml +++ b/OsmAnd/res/values-ka/strings.xml @@ -2449,7 +2449,6 @@ OsmAndის გამოწერა დაპაუზებულია OsmAndის გამოწერა შეჩერებულია URL ყველა პარამეტრით აი ასეთი იქნება: - შეცდომა, გადაამოწმეთ პარამეტრები Mapillary-ის გამოსახულება Mapillary-ის ღილაკი ფერთა გამა diff --git a/OsmAnd/res/values-lt/strings.xml b/OsmAnd/res/values-lt/strings.xml index 65c711462f..09ee2a83fd 100644 --- a/OsmAnd/res/values-lt/strings.xml +++ b/OsmAnd/res/values-lt/strings.xml @@ -2770,7 +2770,6 @@ Tai yra puikus būdas paremti OsmAnd ir OSM, jei jie jums patinka. Patikrinti maršruto apskaičiavimą Dviratis Automobilis - Įvyko klaida, patikrinkite paametrus Kopijuoti adresą Folderiai Pasirinkite folderį diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 04da6132ce..4420cd6987 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -3916,7 +3916,6 @@ Te voet Fiets Auto - Fout, controleer parameters opnieuw Kopieer adres Online routeplanningssysteem Online routeplanningssystemen diff --git a/OsmAnd/res/values-pl/strings.xml b/OsmAnd/res/values-pl/strings.xml index cf4852f488..840fa52189 100644 --- a/OsmAnd/res/values-pl/strings.xml +++ b/OsmAnd/res/values-pl/strings.xml @@ -3956,7 +3956,6 @@ Obliczanie trasy testowej Rower Samochód - Błąd, ponownie sprawdź parametry Skopiuj adres Jazda Stopa diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index da70b09ce8..52d578c035 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -3955,7 +3955,6 @@ Bicicleta Carro - Erro, verifique novamente os parâmetros Copiar endereço Motor de encaminhamento online Mecanismos de roteamento online diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index f5ff13cd8b..aa05e82d25 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -3957,7 +3957,6 @@ A pee Bitzicleta Màchina - Errore, torra a verificare sos paràmetros Còpia s\'indiritzu Motore de càrculu in lìnia Motores de càrculu in lìnia diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 6d8fb45d93..81a9d73353 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -3955,7 +3955,6 @@ Chôdza Bicykel Auto - Chyba, skontrolujte parametre Kopírovať adresu Online navigačná služba Online navigačné služby diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index ee5e25124a..344183c102 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -3961,7 +3961,6 @@ Yürüme Bisiklet Araba - Hata, parametreleri tekrar gözden geçirin Adresi kopyala Çevrim içi yönlendirme motoru Çevrim içi yönlendirme motorları diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 2738eda283..6910c9a902 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -3959,7 +3959,6 @@ Пішки Велосипед Автомобіль - Помилка, повторно перевірте параметри Копіювати адресу Мережний рушій маршрутизації Мережні рушії маршрутизації diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 738ede85e2..0f19668c01 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -3953,7 +3953,6 @@ 步行 自行車 汽車 - 錯誤,重新檢查參數 複製地址 線上路線計算引擎 線上路線計算引擎 diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index bbb71f001a..c755dd11dc 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,21 @@ --> + The name is already exists + Server error: %1$s + MTB + Racing bike + Scooter + Truck + Small truck + HGV + Regular cycling + Road cycling + Mountain cycling + Electric cycling + Walking + Hiking + Wheelchair Announcement time Announcement time of different voice prompts depends on prompt type, current navigation speed and default navigation speed. Time and distance intervals @@ -35,7 +50,6 @@ Online routing engines Online routing engine Copy address - Error, recheck parameters Car Bike Foot diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java index bf4f41a096..b28d98d55f 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingHelper.java @@ -156,7 +156,7 @@ public class OnlineRoutingHelper { try { JSONObject json = new JSONObject(jsonString); readFromJson(json, engines); - } catch (JSONException e) { + } catch (JSONException | IllegalArgumentException e) { LOG.debug("Error when reading engines from JSON ", e); } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java index c7a31fb10c..d676e1e154 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/GraphhopperEngine.java @@ -15,6 +15,8 @@ import org.json.JSONObject; import java.util.List; import java.util.Map; +import static net.osmand.util.Algorithms.isEmpty; + public class GraphhopperEngine extends OnlineRoutingEngine { public GraphhopperEngine(@Nullable Map params) { @@ -62,11 +64,11 @@ public class GraphhopperEngine extends OnlineRoutingEngine { .append('&'); } String vehicle = get(EngineParameter.VEHICLE_KEY); - if (vehicle != null) { + if (isEmpty(vehicle)) { sb.append("vehicle=").append(vehicle); } String apiKey = get(EngineParameter.API_KEY); - if (apiKey != null) { + if (isEmpty(apiKey)) { sb.append('&').append("key=").append(apiKey); } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 9072c7ada0..276837c347 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.util.Algorithms.isEmpty; + public abstract class OnlineRoutingEngine implements Cloneable { public final static String ONLINE_ROUTING_ENGINE_PREFIX = "online_routing_engine_"; @@ -33,7 +35,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { private final Set allowedParameters = new HashSet<>(); public OnlineRoutingEngine(@Nullable Map params) { - if (!Algorithms.isEmpty(params)) { + if (!isEmpty(params)) { this.params.putAll(params); } collectAllowedVehiclesInternal(); @@ -62,13 +64,13 @@ public abstract class OnlineRoutingEngine implements Cloneable { private String getStandardName(@NonNull Context ctx) { String base = getBaseName(ctx); String index = get(EngineParameter.NAME_INDEX); - return !Algorithms.isEmpty(index) ? base + " " + index : base; + return !isEmpty(index) ? base + " " + index : base; } @NonNull public String getBaseName(@NonNull Context ctx) { String vehicleTitle = getSelectedVehicleName(ctx); - if (Algorithms.isEmpty(vehicleTitle)) { + if (isEmpty(vehicleTitle)) { return getType().getTitle(); } else { String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_dash); @@ -79,7 +81,7 @@ public abstract class OnlineRoutingEngine implements Cloneable { @NonNull public String getBaseUrl() { String customUrl = get(EngineParameter.CUSTOM_URL); - if (Algorithms.isEmpty(customUrl)) { + if (isEmpty(customUrl)) { return getStandardUrl(); } return customUrl; @@ -186,10 +188,6 @@ public abstract class OnlineRoutingEngine implements Cloneable { return OnlineRoutingFactory.createEngine(getType(), getParams()); } - protected boolean isEmpty(@Nullable String s) { - return Algorithms.isEmpty(s); - } - @NonNull public static String generateKey() { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 507ecd3af0..594e7e1b36 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -16,6 +16,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import static net.osmand.util.Algorithms.isEmpty; + public class OrsEngine extends OnlineRoutingEngine { public OrsEngine(@Nullable Map params) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java index d88ae42ff7..1ef9c1a622 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OsrmEngine.java @@ -15,6 +15,8 @@ import org.json.JSONObject; import java.util.List; import java.util.Map; +import static net.osmand.util.Algorithms.isEmpty; + public class OsrmEngine extends OnlineRoutingEngine { public OsrmEngine(@Nullable Map params) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java index 7a1f4c6b4b..fa6e2b6b74 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java @@ -156,7 +156,7 @@ public class OnlineRoutingCard extends BaseCard { public void hideFieldBoxError() { hideElements(tvErrorText); if (fieldBoxHelperTextShowed) { - showElements(tvErrorText); + showElements(tvHelperText); } } diff --git a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java index 86b79ed910..fd0f593462 100644 --- a/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java +++ b/OsmAnd/src/net/osmand/plus/profiles/OnlineRoutingEngineDataObject.java @@ -17,10 +17,10 @@ public class OnlineRoutingEngineDataObject extends ProfileDataObject { } @Override - public int compareTo(@NonNull ProfileDataObject another) { - if (another instanceof OnlineRoutingEngineDataObject) { - OnlineRoutingEngineDataObject anotherEngine = (OnlineRoutingEngineDataObject) another; - return Integer.compare(this.order, anotherEngine.order); + public int compareTo(@NonNull ProfileDataObject profileDataObject) { + if (profileDataObject instanceof OnlineRoutingEngineDataObject) { + OnlineRoutingEngineDataObject another = (OnlineRoutingEngineDataObject) profileDataObject; + return (this.order < another.order) ? -1 : ((this.order == another.order) ? 0 : 1); } return 0; } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java index fc71e8d183..cf08142393 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/OnlineRoutingSettingsItem.java @@ -106,7 +106,7 @@ public class OnlineRoutingSettingsItem extends CollectionSettingsItem Date: Mon, 18 Jan 2021 04:38:12 +0200 Subject: [PATCH 19/31] fix used profile color as active color in Textfields; fix equals() in OnlineRoutingEngineObject; fix save\restore initEngine after screen rotation; fix descrease padding below scroll buttons in "Vehicle" block if VehicleType.CUSTOM was saved; --- .../plus/onlinerouting/OnlineRoutingCard.java | 11 ++-- .../OnlineRoutingEngineFragment.java | 54 +++++++++++++------ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java index 0ac677a4ae..888216abb3 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingCard.java @@ -10,6 +10,7 @@ import android.widget.EditText; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -24,6 +25,7 @@ import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.OsmandTextFieldBoxes; import java.util.List; @@ -43,10 +45,12 @@ public class OnlineRoutingCard extends BaseCard { private View bottomDivider; private View button; private OnTextChangedListener onTextChangedListener; + private ApplicationMode appMode; - public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode) { + public OnlineRoutingCard(@NonNull MapActivity mapActivity, boolean nightMode, ApplicationMode appMode) { super(mapActivity); this.nightMode = nightMode; + this.appMode = appMode; } @Override @@ -68,9 +72,8 @@ public class OnlineRoutingCard extends BaseCard { bottomDivider = view.findViewById(R.id.bottom_divider); button = view.findViewById(R.id.button); - textFieldBoxes.setPrimaryColor(nightMode - ? view.getContext().getResources().getColor(R.color.active_color_primary_dark) - : view.getContext().getResources().getColor(R.color.active_color_primary_light)); + int activeColor = ContextCompat.getColor(app, appMode.getIconColorInfo().getColor(nightMode)); + textFieldBoxes.setPrimaryColor(activeColor); editText.addTextChangedListener(new TextWatcher() { @Override diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index d0b8a4db7b..8c457ebbac 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -60,6 +60,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String ENGINE_VEHICLE_TYPE_KEY = "engine_vehicle_type"; private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; private static final String ENGINE_API_KEY_KEY = "engine_api_key"; + private static final String INIT_ENGINE_NAME_KEY = "init_engine_name"; + private static final String INIT_ENGINE_SERVER_KEY = "init_engine_server"; + private static final String INIT_ENGINE_SERVER_URL_KEY = "init_engine_server_url"; + private static final String INIT_ENGINE_VEHICLE_TYPE_KEY = "init_engine_vehicle_type"; + private static final String INIT_ENGINE_CUSTOM_VEHICLE_KEY = "init_engine_custom_vehicle"; + private static final String INIT_ENGINE_API_KEY_KEY = "init_engine_api_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; private static final String EDITED_ENGINE_KEY = "edited_engine_key"; @@ -173,7 +179,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { setupExampleCard(); setupResultsContainer(); addSpaceSegment(); - engine.cloneIn(initEngine); setupButtons(); @@ -257,7 +262,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void setupNameCard() { - nameCard = new OnlineRoutingCard(mapActivity, isNightMode()); + nameCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); nameCard.build(mapActivity); nameCard.setDescription(getString(R.string.select_nav_profile_dialog_message)); nameCard.setEditedText(engine.getName(app)); @@ -275,7 +280,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void setupTypeCard() { - typeCard = new OnlineRoutingCard(mapActivity, isNightMode()); + typeCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); typeCard.build(mapActivity); typeCard.setHeaderTitle(getString(R.string.shared_string_type)); List serverItems = new ArrayList<>(); @@ -310,7 +315,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void setupVehicleCard() { - vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode()); + vehicleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); vehicleCard.build(mapActivity); vehicleCard.setHeaderTitle(getString(R.string.shared_string_vehicle)); List vehicleItems = new ArrayList<>(); @@ -322,20 +327,20 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { @Override public boolean processResult(HorizontalSelectionItem result) { VehicleType vehicle = (VehicleType) result.getObject(); + vehicleCard.updateBottomMarginSelectionMenu(vehicle != VehicleType.CUSTOM ? 0 + : getResources().getDimensionPixelSize(R.dimen.content_padding) + ); if (engine.vehicleType != vehicle) { engine.vehicleType = vehicle; updateCardViews(nameCard, vehicleCard, exampleCard); - if (vehicle == VehicleType.CUSTOM) { - vehicleCard.updateBottomMarginSelectionMenu((int) getResources().getDimension(R.dimen.content_padding)); - } else { - vehicleCard.updateBottomMarginSelectionMenu(0); - } return true; } return false; } }); - vehicleCard.updateBottomMarginSelectionMenu(0); + vehicleCard.updateBottomMarginSelectionMenu(engine.vehicleType != VehicleType.CUSTOM ? 0 + : getResources().getDimensionPixelSize(R.dimen.content_padding) + ); vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { @Override @@ -353,7 +358,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void setupApiKeyCard() { - apiKeyCard = new OnlineRoutingCard(mapActivity, isNightMode()); + apiKeyCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); apiKeyCard.build(mapActivity); apiKeyCard.setHeaderTitle(getString(R.string.shared_string_api_key)); apiKeyCard.setFieldBoxLabelText(getString(R.string.keep_it_empty_if_not)); @@ -370,7 +375,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void setupExampleCard() { - exampleCard = new OnlineRoutingCard(mapActivity, isNightMode()); + exampleCard = new OnlineRoutingCard(mapActivity, isNightMode(), appMode); exampleCard.build(mapActivity); exampleCard.setHeaderTitle(getString(R.string.shared_string_example)); List locationItems = new ArrayList<>(); @@ -603,6 +608,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { outState.putString(ENGINE_VEHICLE_TYPE_KEY, engine.vehicleType.name()); outState.putString(ENGINE_CUSTOM_VEHICLE_KEY, engine.customVehicleKey); outState.putString(ENGINE_API_KEY_KEY, engine.apiKey); + outState.putString(INIT_ENGINE_NAME_KEY, initEngine.customName); + outState.putString(INIT_ENGINE_SERVER_KEY, initEngine.type.name()); + outState.putString(INIT_ENGINE_SERVER_URL_KEY, initEngine.customServerUrl); + outState.putString(INIT_ENGINE_VEHICLE_TYPE_KEY, initEngine.vehicleType.name()); + outState.putString(INIT_ENGINE_CUSTOM_VEHICLE_KEY, initEngine.customVehicleKey); + outState.putString(INIT_ENGINE_API_KEY_KEY, initEngine.apiKey); outState.putString(EXAMPLE_LOCATION_KEY, selectedLocation.name()); if (appMode != null) { outState.putString(APP_MODE_KEY, appMode.getStringKey()); @@ -617,6 +628,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { engine.vehicleType = VehicleType.valueOf(savedState.getString(ENGINE_VEHICLE_TYPE_KEY)); engine.customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); engine.apiKey = savedState.getString(ENGINE_API_KEY_KEY); + initEngine.customName = savedState.getString(INIT_ENGINE_NAME_KEY); + initEngine.type = EngineType.valueOf(savedState.getString(INIT_ENGINE_SERVER_KEY)); + initEngine.customServerUrl = savedState.getString(INIT_ENGINE_SERVER_URL_KEY); + initEngine.vehicleType = VehicleType.valueOf(savedState.getString(INIT_ENGINE_VEHICLE_TYPE_KEY)); + initEngine.customVehicleKey = savedState.getString(INIT_ENGINE_CUSTOM_VEHICLE_KEY); + initEngine.apiKey = savedState.getString(INIT_ENGINE_API_KEY_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); editedEngineKey = savedState.getString(EDITED_ENGINE_KEY); @@ -643,6 +660,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { engine.apiKey = editedEngine.getParameter(EngineParameter.API_KEY); } } + engine.cloneIn(initEngine); } private void dismiss() { @@ -658,7 +676,9 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public void showExitDialog() { View focus = view.findFocus(); AndroidUtils.hideSoftKeyboard(requireMyActivity(), focus); - + if (engine.customName != null && initEngine.customName == null) { + initEngine.customName = initEngine.getName(app); + } if (!engine.equals(initEngine)) { AlertDialog.Builder dismissDialog = createWarningDialog(getActivity(), R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel); @@ -759,12 +779,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { if (obj == null || getClass() != obj.getClass()) return false; OnlineRoutingEngineObject engine = (OnlineRoutingEngineObject) obj; - if (customName != engine.customName) return false; + if (!Algorithms.stringsEqual(customName, engine.customName)) return false; if (type != engine.type) return false; - if (customServerUrl != engine.customServerUrl) return false; + if (!Algorithms.stringsEqual(getBaseUrl(), engine.getBaseUrl())) return false; if (vehicleType != engine.vehicleType) return false; - if (customVehicleKey != engine.customVehicleKey) return false; - return apiKey == engine.apiKey; + if (!Algorithms.stringsEqual(getVehicleKey(), engine.getVehicleKey())) return false; + return Algorithms.isEmpty(apiKey) ? Algorithms.isEmpty(engine.apiKey) : Algorithms.stringsEqual(apiKey, engine.apiKey); } } } From 47ef53fad7897250d2a174c5af500978c2c6d2dc Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 18 Jan 2021 07:48:37 +0200 Subject: [PATCH 20/31] Minor fixes --- .../OnlineRoutingEngineFragment.java | 114 +++++++++--------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java index 8c457ebbac..997b7fb34c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/OnlineRoutingEngineFragment.java @@ -13,6 +13,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ScrollView; @@ -83,7 +84,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private OnlineRoutingCard exampleCard; private View testResultsContainer; private ScrollView scrollView; - private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayout; + private OnGlobalLayoutListener onGlobalLayout; private boolean isKeyboardShown = false; private ApplicationMode appMode; @@ -161,8 +162,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { view = getInflater().inflate( R.layout.online_routing_engine_fragment, container, false); segmentsContainer = (ViewGroup) view.findViewById(R.id.segments_container); @@ -186,14 +187,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { scrollView.setOnTouchListener(new View.OnTouchListener() { int scrollViewY = 0; + @Override public boolean onTouch(View v, MotionEvent event) { int y = scrollView.getScrollY(); if (isKeyboardShown && scrollViewY != y) { scrollViewY = y; - View focus = getActivity().getCurrentFocus(); + View focus = mapActivity.getCurrentFocus(); if (focus != null) { - AndroidUtils.hideSoftKeyboard(requireActivity(), focus); + AndroidUtils.hideSoftKeyboard(mapActivity, focus); focus.clearFocus(); } } @@ -206,59 +208,56 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private int layoutHeightMin; @Override - public void onGlobalLayout() { + public void onGlobalLayout() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(this); + } - final ViewTreeObserver.OnGlobalLayoutListener listener = this; + Rect visibleDisplayFrame = new Rect(); + view.getWindowVisibleDisplayFrame(visibleDisplayFrame); + int layoutHeight = visibleDisplayFrame.bottom; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } else { - view.getViewTreeObserver().removeGlobalOnLayoutListener(this); - } - - Rect visibleDisplayFrame = new Rect(); - view.getWindowVisibleDisplayFrame(visibleDisplayFrame); - int layoutHeight = visibleDisplayFrame.bottom; - - if (layoutHeight < layoutHeightPrevious) { + if (layoutHeight < layoutHeightPrevious) { isKeyboardShown = true; layoutHeightMin = layoutHeight; } else { - isKeyboardShown = layoutHeight == layoutHeightMin; + isKeyboardShown = layoutHeight == layoutHeightMin; } if (layoutHeight != layoutHeightPrevious) { - FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams(); - rootViewLayout.height = layoutHeight; - view.requestLayout(); - layoutHeightPrevious = layoutHeight; - } + FrameLayout.LayoutParams rootViewLayout = (FrameLayout.LayoutParams) view.getLayoutParams(); + rootViewLayout.height = layoutHeight; + view.requestLayout(); + layoutHeightPrevious = layoutHeight; + } - view.post(new Runnable() { - @Override - public void run() { - view.getViewTreeObserver().addOnGlobalLayoutListener(listener); - } - }); + view.post(new Runnable() { + @Override + public void run() { + view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); + } + }); - } - }; + } + }; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayout); + } - return view; + return view; } @Override public void onDestroyView() { super.onDestroyView(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); - } else { - view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); + } } private void setupNameCard() { @@ -327,9 +326,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { @Override public boolean processResult(HorizontalSelectionItem result) { VehicleType vehicle = (VehicleType) result.getObject(); - vehicleCard.updateBottomMarginSelectionMenu(vehicle != VehicleType.CUSTOM ? 0 - : getResources().getDimensionPixelSize(R.dimen.content_padding) - ); if (engine.vehicleType != vehicle) { engine.vehicleType = vehicle; updateCardViews(nameCard, vehicleCard, exampleCard); @@ -338,9 +334,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return false; } }); - vehicleCard.updateBottomMarginSelectionMenu(engine.vehicleType != VehicleType.CUSTOM ? 0 - : getResources().getDimensionPixelSize(R.dimen.content_padding) - ); vehicleCard.setFieldBoxLabelText(getString(R.string.shared_string_custom)); vehicleCard.setOnTextChangedListener(new OnTextChangedListener() { @Override @@ -482,7 +475,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } else { vehicleCard.hideFieldBox(); } - + int contentPadding = getResources().getDimensionPixelSize(R.dimen.content_padding); + vehicleCard.updateBottomMarginSelectionMenu(engine.vehicleType != VehicleType.CUSTOM ? 0 : contentPadding); } else if (exampleCard.equals(card)) { exampleCard.setEditedText(getTestUrl()); } @@ -675,12 +669,12 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { public void showExitDialog() { View focus = view.findFocus(); - AndroidUtils.hideSoftKeyboard(requireMyActivity(), focus); + AndroidUtils.hideSoftKeyboard(mapActivity, focus); if (engine.customName != null && initEngine.customName == null) { initEngine.customName = initEngine.getName(app); } if (!engine.equals(initEngine)) { - AlertDialog.Builder dismissDialog = createWarningDialog(getActivity(), + AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity, R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel); dismissDialog.setPositiveButton(R.string.shared_string_exit, new DialogInterface.OnClickListener() { @Override @@ -694,14 +688,14 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } } - private AlertDialog.Builder createWarningDialog(Activity activity, int title, int message, int negButton) { - Context themedContext = UiUtilities.getThemedContext(activity, isNightMode()); - AlertDialog.Builder warningDialog = new AlertDialog.Builder(themedContext); - warningDialog.setTitle(getString(title)); - warningDialog.setMessage(getString(message)); - warningDialog.setNegativeButton(negButton, null); - return warningDialog; - } + private AlertDialog.Builder createWarningDialog(Activity activity, int title, int message, int negButton) { + Context themedContext = UiUtilities.getThemedContext(activity, isNightMode()); + AlertDialog.Builder warningDialog = new AlertDialog.Builder(themedContext); + warningDialog.setTitle(getString(title)); + warningDialog.setMessage(getString(message)); + warningDialog.setNegativeButton(negButton, null); + return warningDialog; + } private boolean isNightMode() { return !app.getSettings().isLightContentForMode(appMode); @@ -722,8 +716,8 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } public static void showInstance(@NonNull FragmentActivity activity, - @NonNull ApplicationMode appMode, - String editedEngineKey) { + @NonNull ApplicationMode appMode, + String editedEngineKey) { FragmentManager fm = activity.getSupportFragmentManager(); if (!fm.isStateSaved() && fm.findFragmentByTag(OnlineRoutingEngineFragment.TAG) == null) { OnlineRoutingEngineFragment fragment = new OnlineRoutingEngineFragment(); From 8dceee3eb08ce279d0c508c4351e6a649f48845f Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 18 Jan 2021 09:47:08 +0300 Subject: [PATCH 21/31] Quick fix android-lib --- OsmAnd/build.gradle.lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/build.gradle.lib b/OsmAnd/build.gradle.lib index 6b0f4da990..1f731106fb 100644 --- a/OsmAnd/build.gradle.lib +++ b/OsmAnd/build.gradle.lib @@ -38,7 +38,7 @@ android { jni.srcDirs = [] jniLibs.srcDirs = ["libs"] aidl.srcDirs = ["src"] - java.srcDirs = ["src", "src-google"] + java.srcDirs = ["src", "src-gms", "src-google"] resources.srcDirs = ["src"] renderscript.srcDirs = ["src"] res.srcDirs = ["res"] From df264356c1a5b69ef458d48616e2e18f00acb2b0 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Mon, 18 Jan 2021 09:51:39 +0300 Subject: [PATCH 22/31] Quick fix android-lib (added gms dependency) --- OsmAnd/build.gradle.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/build.gradle.lib b/OsmAnd/build.gradle.lib index 1f731106fb..f4f9c019ed 100644 --- a/OsmAnd/build.gradle.lib +++ b/OsmAnd/build.gradle.lib @@ -409,6 +409,7 @@ dependencies { exclude group: "com.fasterxml.jackson.core" } implementation 'com.jaredrummler:colorpicker:1.1.0' - implementation 'org.bouncycastle:bcpkix-jdk15on:1.56' + + implementation 'com.google.android.gms:play-services-location:17.1.0' } From 29daef559492a6bff93990dee3c59939a25a0641 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 18 Jan 2021 11:32:15 +0200 Subject: [PATCH 23/31] merge ui and backend fixes --- .../engine/OnlineRoutingEngine.java | 10 ++ .../ui/OnlineRoutingEngineFragment.java | 124 +++++------------- 2 files changed, 45 insertions(+), 89 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java index 276837c347..e3f2d416ce 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OnlineRoutingEngine.java @@ -192,4 +192,14 @@ public abstract class OnlineRoutingEngine implements Cloneable { public static String generateKey() { return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof OnlineRoutingEngine)) return false; + + OnlineRoutingEngine engine = (OnlineRoutingEngine) o; + if (getType() != engine.getType()) return false; + return Algorithms.objectEquals(getParams(), engine.getParams()); + } } diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index d4731cddad..d362898275 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -62,13 +62,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private static final String ENGINE_TYPE_KEY = "engine_type"; private static final String ENGINE_CUSTOM_VEHICLE_KEY = "engine_custom_vehicle"; - private static final String ENGINE_API_KEY_KEY = "engine_api_key"; - private static final String INIT_ENGINE_NAME_KEY = "init_engine_name"; - private static final String INIT_ENGINE_SERVER_KEY = "init_engine_server"; - private static final String INIT_ENGINE_SERVER_URL_KEY = "init_engine_server_url"; - private static final String INIT_ENGINE_VEHICLE_TYPE_KEY = "init_engine_vehicle_type"; - private static final String INIT_ENGINE_CUSTOM_VEHICLE_KEY = "init_engine_custom_vehicle"; - private static final String INIT_ENGINE_API_KEY_KEY = "init_engine_api_key"; private static final String EXAMPLE_LOCATION_KEY = "example_location"; private static final String APP_MODE_KEY = "app_mode"; private static final String EDITED_ENGINE_KEY = "edited_engine_key"; @@ -92,6 +85,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { private boolean isKeyboardShown = false; private OnlineRoutingEngine engine; + private OnlineRoutingEngine initEngine; private String customVehicleKey; private ExampleLocation selectedLocation; private String editedEngineKey; @@ -208,23 +202,13 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return view; } - @Override - public void onDestroyView() { - super.onDestroyView(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); - } else { - view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); - } - } - private void setupToolbar(Toolbar toolbar) { ImageView navigationIcon = toolbar.findViewById(R.id.close_button); navigationIcon.setImageResource(R.drawable.ic_action_close); navigationIcon.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - dismiss(); + showExitDialog(); } }); TextView title = toolbar.findViewById(R.id.toolbar_title); @@ -581,25 +565,11 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { exampleCard.setEditedText(getTestUrl()); } } - engine.cloneIn(initEngine); - } - - private void dismiss() { - FragmentActivity activity = getActivity(); - if (activity != null) { - FragmentManager fragmentManager = activity.getSupportFragmentManager(); - if (!fragmentManager.isStateSaved()) { - fragmentManager.popBackStack(); - } - } } public void showExitDialog() { View focus = view.findFocus(); AndroidUtils.hideSoftKeyboard(mapActivity, focus); - if (engine.customName != null && initEngine.customName == null) { - initEngine.customName = initEngine.getName(app); - } if (!engine.equals(initEngine)) { AlertDialog.Builder dismissDialog = createWarningDialog(mapActivity, R.string.shared_string_dismiss, R.string.exit_without_saving, R.string.shared_string_cancel); @@ -624,6 +594,16 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return warningDialog; } + private void dismiss() { + FragmentActivity activity = getActivity(); + if (activity != null) { + FragmentManager fragmentManager = activity.getSupportFragmentManager(); + if (!fragmentManager.isStateSaved()) { + fragmentManager.popBackStack(); + } + } + } + private boolean isNightMode() { return !app.getSettings().isLightContentForMode(getAppMode()); } @@ -647,6 +627,16 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { return UiUtilities.getInflater(mapActivity, isNightMode()); } + @Override + public void onDestroyView() { + super.onDestroyView(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + view.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayout); + } else { + view.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayout); + } + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -668,6 +658,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void restoreState(@NonNull Bundle savedState) { + initEngine = createInitStateEngine(); String typeKey = savedState.getString(ENGINE_TYPE_KEY); EngineType type = EngineType.getTypeByName(typeKey); engine = OnlineRoutingFactory.createEngine(type); @@ -684,22 +675,30 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void initState() { + initEngine = createInitStateEngine(); selectedLocation = ExampleLocation.values()[0]; + engine = (OnlineRoutingEngine) initEngine.clone(); + if (Algorithms.objectEquals(engine.getSelectedVehicleType(), CUSTOM_VEHICLE)) { + customVehicleKey = engine.get(EngineParameter.VEHICLE_KEY); + } else { + customVehicleKey = ""; + } + } + + private OnlineRoutingEngine createInitStateEngine() { + OnlineRoutingEngine engine; OnlineRoutingEngine editedEngine = helper.getEngineByKey(editedEngineKey); if (editedEngine != null) { engine = (OnlineRoutingEngine) editedEngine.clone(); - if (Algorithms.objectEquals(engine.getSelectedVehicleType(), CUSTOM_VEHICLE)) { - customVehicleKey = engine.get(EngineParameter.VEHICLE_KEY); - } } else { engine = OnlineRoutingFactory.createEngine(EngineType.values()[0]); String vehicle = engine.getAllowedVehicles().get(0).getKey(); engine.put(EngineParameter.VEHICLE_KEY, vehicle); - customVehicleKey = ""; if (editedEngineKey != null) { engine.put(EngineParameter.KEY, editedEngineKey); } } + return engine; } public static void showInstance(@NonNull FragmentActivity activity, @@ -715,57 +714,4 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { .addToBackStack(TAG).commitAllowingStateLoss(); } } - - private static class OnlineRoutingEngineObject { - private String customName; - private EngineType type; - private String customServerUrl; - private VehicleType vehicleType; - private String customVehicleKey; - private String apiKey; - - public String getVehicleKey() { - if (vehicleType == VehicleType.CUSTOM) { - return customVehicleKey; - } - return vehicleType.getKey(); - } - - public String getName(Context ctx) { - if (customName != null) { - return customName; - } - return OnlineRoutingEngine.getStandardName(ctx, type, getVehicleKey()); - } - - public String getBaseUrl() { - if (Algorithms.isEmpty(customServerUrl)) { - return type.getStandardUrl(); - } - return customServerUrl; - } - - public void cloneIn(OnlineRoutingEngineObject clone) { - clone.customName = customName; - clone.type = type; - clone.customServerUrl = customServerUrl; - clone.vehicleType = vehicleType; - clone.customVehicleKey = customVehicleKey; - clone.apiKey = apiKey; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - OnlineRoutingEngineObject engine = (OnlineRoutingEngineObject) obj; - if (!Algorithms.stringsEqual(customName, engine.customName)) return false; - if (type != engine.type) return false; - if (!Algorithms.stringsEqual(getBaseUrl(), engine.getBaseUrl())) return false; - if (vehicleType != engine.vehicleType) return false; - if (!Algorithms.stringsEqual(getVehicleKey(), engine.getVehicleKey())) return false; - return Algorithms.isEmpty(apiKey) ? Algorithms.isEmpty(engine.apiKey) : Algorithms.stringsEqual(apiKey, engine.apiKey); - } - } } From f26a5471039088a9698f11adeb6da9b416d002d2 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 18 Jan 2021 11:35:12 +0200 Subject: [PATCH 24/31] merge ui and backend fixes p.2 --- OsmAnd/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 3e675136d7..8605ea2189 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,8 +12,6 @@ --> - Show track on map - Start recording The name is already exists Server error: %1$s MTB @@ -29,6 +27,8 @@ Walking Hiking Wheelchair + Show track on map + Start recording Announcement time Announcement time of different voice prompts depends on prompt type, current navigation speed and default navigation speed. Time and distance intervals From d5d32b7674c7197f6c88dc36478e258e0be89ec8 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 18 Jan 2021 13:18:51 +0200 Subject: [PATCH 25/31] Fix "exit confirmation dialog is displayed every time after screen was flipped" --- .../plus/onlinerouting/ui/OnlineRoutingEngineFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index d362898275..433fda973c 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -658,6 +658,7 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { } private void restoreState(@NonNull Bundle savedState) { + editedEngineKey = savedState.getString(EngineParameter.KEY.name()); initEngine = createInitStateEngine(); String typeKey = savedState.getString(ENGINE_TYPE_KEY); EngineType type = EngineType.getTypeByName(typeKey); @@ -671,7 +672,6 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { customVehicleKey = savedState.getString(ENGINE_CUSTOM_VEHICLE_KEY); selectedLocation = ExampleLocation.valueOf(savedState.getString(EXAMPLE_LOCATION_KEY)); appMode = ApplicationMode.valueOfStringKey(savedState.getString(APP_MODE_KEY), null); - editedEngineKey = savedState.getString(EngineParameter.KEY.name()); } private void initState() { From c7dcc9b0cef2da3436219f403d3bd95234bf6515 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 18 Jan 2021 13:48:05 +0200 Subject: [PATCH 26/31] Fix OpenRouteService parsing --- .../net/osmand/plus/onlinerouting/engine/OrsEngine.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java index 594e7e1b36..7c57737d46 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/engine/OrsEngine.java @@ -69,9 +69,9 @@ public class OrsEngine extends OnlineRoutingEngine { LatLon start = path.get(0); LatLon end = path.get(path.size() - 1); sb.append('&').append("start=") - .append(start.getLatitude()).append(',').append(start.getLongitude()); + .append(start.getLongitude()).append(',').append(start.getLatitude()); sb.append('&').append("end=") - .append(end.getLatitude()).append(',').append(end.getLongitude()); + .append(end.getLongitude()).append(',').append(end.getLatitude()); } } @@ -84,8 +84,8 @@ public class OrsEngine extends OnlineRoutingEngine { List track = new ArrayList<>(); for (int i = 0; i < array.length(); i++) { JSONArray point = array.getJSONArray(i); - double lat = Double.parseDouble(point.getString(0)); - double lon = Double.parseDouble(point.getString(1)); + double lon = Double.parseDouble(point.getString(0)); + double lat = Double.parseDouble(point.getString(1)); track.add(new LatLon(lat, lon)); } return track; From 67f5beba7870b924653f3a56e6b39db285d0fb2a Mon Sep 17 00:00:00 2001 From: androiddevkkotlin Date: Mon, 18 Jan 2021 15:20:22 +0200 Subject: [PATCH 27/31] All map widgets / topbar for markers - zoom context menu --- OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java | 2 -- OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java | 2 +- .../src/net/osmand/plus/views/layers/MapQuickActionLayer.java | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index 48dcc7fb6e..28b9d04f46 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -324,7 +324,6 @@ public class ContextMenuLayer extends OsmandMapLayer { } return false; } - hideVisibleMenues(); LatLon pointLatLon = tileBox.getLatLonFromPixel(point.x, point.y); menu.show(pointLatLon, null, null); @@ -805,7 +804,6 @@ public class ContextMenuLayer extends OsmandMapLayer { return true; } else if (selectedObjects.size() > 1) { - hideVisibleMenues(); selectedObjectContextMenuProvider = null; showContextMenuForSelectedObjects(pointLatLon, selectedObjects); return true; diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 5bea819018..daae788cb3 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -877,7 +877,7 @@ public class MapControlsLayer extends OsmandMapLayer { menuControl.updateVisibility(showBottomMenuButtons); boolean showZoomButtons = !routeDialogOpened && !contextMenuOpened && !isInTrackAppearanceMode() - && !isInTrackMenuMode() && (!isInGpxApproximationMode() || !isPotrait()) + && (!isInGpxApproximationMode() || !isPotrait()) && !isInFollowTrackMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !portrait); mapZoomIn.updateVisibility(showZoomButtons); mapZoomOut.updateVisibility(showZoomButtons); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index 4ba977235e..fe4b73dfba 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -425,7 +425,6 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe measurementToolLayer.isInMeasurementMode() || mapMarkersLayer.isInPlanRouteMode() || gpxLayer.isInTrackAppearanceMode() || - mapControlsLayer.isInTrackMenuMode() || mapRouteInfoMenu.isVisible() || MapRouteInfoMenu.chooseRoutesVisible || MapRouteInfoMenu.waypointsVisible || From a2e181ee70c6dcb5e53b12065ad03d8f5165393a Mon Sep 17 00:00:00 2001 From: androiddevkkotlin Date: Mon, 18 Jan 2021 15:46:50 +0200 Subject: [PATCH 28/31] isInTrackAppearanceMode() --- .../osmand/plus/views/layers/MapControlsLayer.java | 11 ++++------- .../plus/views/mapwidgets/MapInfoWidgetsFactory.java | 1 - .../views/mapwidgets/MapMarkersWidgetsFactory.java | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index daae788cb3..e4fe3a484c 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -871,8 +871,7 @@ public class MapControlsLayer extends OsmandMapLayer { boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode) && !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode() && !isInPlanRouteMode() && !contextMenuOpened && !isInChoosingRoutesMode() - && !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode() - && !isInTrackMenuMode(); + && !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode(); routePlanningBtn.updateVisibility(showBottomMenuButtons); menuControl.updateVisibility(showBottomMenuButtons); @@ -883,7 +882,7 @@ public class MapControlsLayer extends OsmandMapLayer { mapZoomOut.updateVisibility(showZoomButtons); boolean forceHideCompass = routeDialogOpened || trackDialogOpened || isInMeasurementToolMode() - || isInPlanRouteMode() || contextMenuOpened || isInChoosingRoutesMode() || isInTrackMenuMode() + || isInPlanRouteMode() || contextMenuOpened || isInChoosingRoutesMode() || isInTrackAppearanceMode() || isInWaypointsChoosingMode() || isInFollowTrackMode(); compassHud.forceHideCompass = forceHideCompass; compassHud.updateVisibility(!forceHideCompass && shouldShowCompass()); @@ -895,8 +894,7 @@ public class MapControlsLayer extends OsmandMapLayer { } boolean showTopButtons = !routeDialogOpened && !trackDialogOpened && !contextMenuOpened && !isInMeasurementToolMode() && !isInPlanRouteMode() && !isInChoosingRoutesMode() - && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode() - && !isInTrackMenuMode(); + && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode(); layersHud.updateVisibility(showTopButtons); quickSearchHud.updateVisibility(showTopButtons); @@ -1023,8 +1021,7 @@ public class MapControlsLayer extends OsmandMapLayer { boolean tracked = mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); boolean visible = !(tracked && rh.isFollowingMode()) && (!isInGpxApproximationMode() || !isPotrait()); backToLocationControl.updateVisibility(visible && !dialogOpened && !isInPlanRouteMode() - && !isInTrackAppearanceMode() && !isInTrackMenuMode() - && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !isInFollowTrackMode() || !isPotrait())); + && !isInTrackAppearanceMode() && (!isInChoosingRoutesMode() || !isInWaypointsChoosingMode() || !isInFollowTrackMode() || !isPotrait())); } public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index 6e14e1164f..fca0ae429e 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -1235,7 +1235,6 @@ public class MapInfoWidgetsFactory { boolean visible = settings.SHOW_COORDINATES_WIDGET.get() && map.getContextMenu().shouldShowTopControls() && map.getMapRouteInfoMenu().shouldShowTopControls() && !map.isTopToolbarActive() && !map.getMapLayers().getGpxLayer().isInTrackAppearanceMode() - && !map.getMapLayers().getMapControlsLayer().isInTrackMenuMode() && !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible && !MapRouteInfoMenu.followTrackVisible; diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java index a38de7d17b..f47c0f8bd6 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java @@ -193,8 +193,7 @@ public class MapMarkersWidgetsFactory { || map.isTopToolbarActive() || !map.getContextMenu().shouldShowTopControls() || map.getMapLayers().getGpxLayer().isInTrackAppearanceMode() - || map.getMapLayers().getMapMarkersLayer().isInPlanRouteMode() - || map.getMapLayers().getMapControlsLayer().isInTrackMenuMode()) { + || map.getMapLayers().getMapMarkersLayer().isInPlanRouteMode()) { updateVisibility(false); return; } From eec128c1607a0e0263bb8a6a4b04d117a0ec1f3a Mon Sep 17 00:00:00 2001 From: androiddevkkotlin Date: Mon, 18 Jan 2021 15:57:58 +0200 Subject: [PATCH 29/31] Undo unnecessary changes --- OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java index 28b9d04f46..48dcc7fb6e 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/ContextMenuLayer.java @@ -324,6 +324,7 @@ public class ContextMenuLayer extends OsmandMapLayer { } return false; } + hideVisibleMenues(); LatLon pointLatLon = tileBox.getLatLonFromPixel(point.x, point.y); menu.show(pointLatLon, null, null); @@ -804,6 +805,7 @@ public class ContextMenuLayer extends OsmandMapLayer { return true; } else if (selectedObjects.size() > 1) { + hideVisibleMenues(); selectedObjectContextMenuProvider = null; showContextMenuForSelectedObjects(pointLatLon, selectedObjects); return true; From c5447af09c9f18ccb825cca3b50ec90ded84a15a Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 18 Jan 2021 15:58:14 +0200 Subject: [PATCH 30/31] fix descrease padding below scroll buttons in "Vehicle" block; fix saving api key. --- .../onlinerouting/ui/OnlineRoutingCard.java | 17 ++++++++++++++--- .../ui/OnlineRoutingEngineFragment.java | 6 +++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java index cb40a2a192..4403d512f4 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingCard.java @@ -25,6 +25,8 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener; import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem; +import net.osmand.plus.onlinerouting.VehicleType; +import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.widgets.OsmandTextFieldBoxes; @@ -135,14 +137,23 @@ public class OnlineRoutingCard extends BaseCard { if (callback.processResult(item)) { adapter.setSelectedItem(item); } + Object obj = item.getObject(); + updateBottomMarginSelectionMenu(obj); } }); + Object item = adapter.getItemByTitle(selectedItemTitle).getObject(); + updateBottomMarginSelectionMenu(item); rvSelectionMenu.setAdapter(adapter); } - public void updateBottomMarginSelectionMenu(int bottomMargin) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); - params.bottomMargin = bottomMargin; + private void updateBottomMarginSelectionMenu(Object item) { + if (item instanceof VehicleType) { + VehicleType vt = (VehicleType) item; + boolean hasPadding = vt.equals(OnlineRoutingEngine.CUSTOM_VEHICLE); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) rvSelectionMenu.getLayoutParams(); + int contentPadding = app.getResources().getDimensionPixelSize(R.dimen.content_padding); + params.bottomMargin = hasPadding ? contentPadding : 0; + } } public void setDescription(@NonNull String description) { diff --git a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java index d362898275..03ad725444 100644 --- a/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java +++ b/OsmAnd/src/net/osmand/plus/onlinerouting/ui/OnlineRoutingEngineFragment.java @@ -342,7 +342,11 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment { apiKeyCard.setOnTextChangedListener(new OnTextChangedListener() { @Override public void onTextChanged(boolean editedByUser, @NonNull String text) { - engine.put(EngineParameter.API_KEY, text); + if (Algorithms.isBlank(text)) { + engine.remove(EngineParameter.API_KEY); + } else { + engine.put(EngineParameter.API_KEY, text); + } updateCardViews(exampleCard); } }); From cb0adaeed88d4540280d65aeaf5b2194dcc046f0 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 18 Jan 2021 17:32:21 +0200 Subject: [PATCH 31/31] Fix getDistance --- .../plus/wikivoyage/WikivoyageWebViewClient.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java index beafb51ec4..006e010059 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageWebViewClient.java @@ -12,8 +12,6 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import com.jwetherell.openmap.common.MoreMath; - import net.osmand.AndroidUtils; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; @@ -27,11 +25,11 @@ import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelArticle.TravelArticleIdentifier; import net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity; +import net.osmand.util.MapUtils; import java.io.File; import java.util.List; -import static com.jwetherell.openmap.common.LatLonPoint.EQUIVALENT_TOLERANCE; import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKIVOYAGE_DOMAIN; import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKI_DOMAIN; @@ -43,6 +41,7 @@ import static net.osmand.plus.wikipedia.WikiArticleHelper.WIKI_DOMAIN; public class WikivoyageWebViewClient extends WebViewClient { private static final String TAG = WikivoyageWebViewClient.class.getSimpleName(); + public static final int ROUNDING_ERROR = 3; private OsmandApplication app; private FragmentManager fragmentManager; @@ -101,15 +100,15 @@ public class WikivoyageWebViewClient extends WebViewClient { return true; } for (WptPt point : points) { - if (MoreMath.approximately_equal(point.getLatitude(), lat, EQUIVALENT_TOLERANCE * 2) - && MoreMath.approximately_equal(point.getLongitude(), lon, EQUIVALENT_TOLERANCE * 2)) { + if (MapUtils.getDistance(point.getLatitude(), point.getLongitude(), lat, lon) < ROUNDING_ERROR) { gpxPoint = point; break; } } if (gpxPoint != null) { final OsmandSettings settings = app.getSettings(); - settings.setMapLocationToShow(lat, lon, settings.getLastKnownMapZoom(), + settings.setMapLocationToShow(gpxPoint.getLatitude(), gpxPoint.getLongitude(), + settings.getLastKnownMapZoom(), new PointDescription(PointDescription.POINT_TYPE_WPT, gpxPoint.name), false, gpxPoint);