From 3228d7c4fe37c594b7995a01e132a1ff50fe1a97 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk Date: Sat, 16 Jul 2022 23:20:41 +0300 Subject: [PATCH 1/2] New API --- README.md | 15 +- .../main/java/app/organicmaps/api/Api.java | 154 -------------- .../main/java/app/organicmaps/api/Const.java | 41 ++-- .../app/organicmaps/api/CrosshairRequest.java | 55 +++++ .../app/organicmaps/api/DownloadDialog.java | 5 +- .../java/app/organicmaps/api/MapRequest.java | 111 ++++++++++ .../{Response.java => PickPointResponse.java} | 63 +++--- .../main/java/app/organicmaps/api/Point.java | 26 +-- .../java/app/organicmaps/api/Request.java | 194 ------------------ sample-app-capitals/build.gradle | 2 - .../sample/capitals/CapitalsListActivity.java | 33 ++- .../organicmaps/api/sample/capitals/City.java | 4 +- .../sample/capitals/CityDetailsActivity.java | 102 +++++---- .../src/main/res/values/strings.xml | 1 + sample-pick-point/.gitignore | 1 + sample-pick-point/build.gradle | 31 +++ sample-pick-point/proguard-rules.pro | 21 ++ .../src/main/AndroidManifest.xml | 22 ++ .../api/sample/pick_point/MainActivity.java | 60 ++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 +++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++++ .../src/main/res/layout/activity_main.xml | 16 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes .../src/main/res/values/strings.xml | 6 + settings.gradle | 1 + 36 files changed, 675 insertions(+), 499 deletions(-) delete mode 100644 lib/src/main/java/app/organicmaps/api/Api.java create mode 100644 lib/src/main/java/app/organicmaps/api/CrosshairRequest.java create mode 100644 lib/src/main/java/app/organicmaps/api/MapRequest.java rename lib/src/main/java/app/organicmaps/api/{Response.java => PickPointResponse.java} (50%) delete mode 100644 lib/src/main/java/app/organicmaps/api/Request.java create mode 100644 sample-pick-point/.gitignore create mode 100644 sample-pick-point/build.gradle create mode 100644 sample-pick-point/proguard-rules.pro create mode 100644 sample-pick-point/src/main/AndroidManifest.xml create mode 100644 sample-pick-point/src/main/java/app/organicmaps/api/sample/pick_point/MainActivity.java create mode 100644 sample-pick-point/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 sample-pick-point/src/main/res/drawable/ic_launcher_background.xml create mode 100644 sample-pick-point/src/main/res/layout/activity_main.xml create mode 100644 sample-pick-point/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 sample-pick-point/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 sample-pick-point/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 sample-pick-point/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 sample-pick-point/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 sample-pick-point/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 sample-pick-point/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 sample-pick-point/src/main/res/values/strings.xml diff --git a/README.md b/README.md index 8f357dd..5c28ed9 100644 --- a/README.md +++ b/README.md @@ -30,9 +30,8 @@ You don't need any additional permissions in your AndroidManifest.xml to use API ## Classes Overview and HOW TO Core classes you will work with are: -* [app.organicmaps.api.Api][linkApiClass] - static class with methods such as `showPointOnMap(Activity, double, double, String)` etc. * [app.organicmaps.api.Point][linkPointClass] - model of POI, includes lat, lon, name, id, and style data. -* [app.organicmaps.api.Response][linkRespClass] - helps you to extract response from Organic Maps by applying `Response.extractFromIntent(Intent)` to Intent. Contains Point data. +* [app.organicmaps.api.PickPointResponse][linkRespClass] - helps you to extract response from Organic Maps by applying `Response.extractFromIntent(Intent)` to Intent. Contains Point data. ### Show Points on the Map @@ -124,13 +123,12 @@ your application when user press "More Info" button : ## FAQ -#### How should I detect if user has Organic Maps installed? -`Api.isOrganicMapsInstalled(Context)` will return `true` if user has *Lite* or *Pro* version that supports API call installed. - #### Which versions of Organic Maps support API calls? -All versions since 2.4.0 and above support API calls. + +All versions since 2022-07-26 and above support API calls. #### What will happen if I call for `Api.showPoint()` but Organic Maps application is not installed? + Nothing serious. API library will show simple dialog with gentle offer to download Organic Maps. You can see how it looks like below. ![Please install us](site/images/dlg.png) @@ -143,8 +141,11 @@ Nothing serious. API library will show simple dialog with gentle offer to downlo ## API Code License Copyright (c) 2022, Organic Maps OÜ. + Copyright (c) 2019, MY.COM B.V. + Copyright (c) 2013, MapsWithMe GmbH. + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -161,5 +162,5 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND [linkIntents]: http://developer.android.com/guide/components/intents-filters.html "Intents and Intent Filters" [linkApiClass]: lib/src/app/organicmaps/api/Api.java "Api.java" [linkPointClass]: lib/src/app/organicmaps/api/Point.java "Point.java" -[linkRespClass]: lib/src/app/organicmaps/api/Response.java "Response.java" +[linkRespClass]: lib/src/app/organicmaps/api/PickPointResponse.java "PickPointResponse.java" [linkSampleSource]: https://github.com/organicmaps/api-android/tree/master/sample-app-capitals "Api Source Code" diff --git a/lib/src/main/java/app/organicmaps/api/Api.java b/lib/src/main/java/app/organicmaps/api/Api.java deleted file mode 100644 index 6848378..0000000 --- a/lib/src/main/java/app/organicmaps/api/Api.java +++ /dev/null @@ -1,154 +0,0 @@ -/****************************************************************************** - Copyright (c) 2022, Organic Maps OÜ. All rights reserved. - Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. Redistributions in binary form must - reproduce the above copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with the - distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. - ******************************************************************************/ -package app.organicmaps.api; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; - - -public final class Api -{ - - /** - * Most detailed level, buildings and trees are seen. - */ - public static final double ZOOM_MAX = 19; - /** - * Least detailed level, continents are seen. - */ - public static final double ZOOM_MIN = 1; - - public static void showOrganicMapsUrl(Activity caller, PendingIntent pendingIntent, double zoomLevel, String url) - { - final Uri uri = Uri.parse(url); - final String[] latlon = uri.getQueryParameter("ll").split(","); - final double lat = Double.parseDouble(latlon[0]); - final double lon = Double.parseDouble(latlon[1]); - final String name = uri.getQueryParameter("n"); - final String id = uri.getQueryParameter("id"); - - showPointsOnMap(caller, name, zoomLevel, pendingIntent, new Point(lat, lon, name, id)); - } - - public static void sendRequest(Activity caller, Request request) - { - final Intent mwmIntent = request.toIntent(caller); - - if (isOrganicMapsInstalled(caller)) - { - caller.startActivity(mwmIntent); - } - else - (new DownloadDialog(caller)).show(); - } - - /** - * Shows single point on the map. - * - * @param caller - * @param lat - * @param lon - * @param name - */ - public static void showPointOnMap(Activity caller, double lat, double lon, String name) - { - showPointsOnMap(caller, null, (PendingIntent) null, new Point(lat, lon, name)); - } - - /** - * Shows single point on the map using specified zoom level in range from - * {@link Api#ZOOM_MIN} to {@link Api#ZOOM_MAX}. - * - * @param caller - * @param lat - * @param lon - * @param name - * @param zoomLevel - */ - public static void showPointOnMap(Activity caller, double lat, double lon, String name, double zoomLevel) - { - showPointsOnMap(caller, null, zoomLevel, null, new Point(lat, lon, name)); - } - - /** - * Shows set of points on the map. - * - * @param caller - * @param title - * @param points - */ - public static void showPointsOnMap(Activity caller, String title, Point... points) - { - showPointsOnMap(caller, title, null, points); - } - - /** - * Shows set of points on the maps and allows OrganicMapsApplication to send - * {@link PendingIntent} provided by client application. - * - * @param caller - * @param title - * @param pendingIntent - * @param points - */ - public static void showPointsOnMap(Activity caller, String title, PendingIntent pendingIntent, Point... points) - { - showPointsOnMap(caller, title, -1, pendingIntent, points); - } - - private static void showPointsOnMap(Activity caller, String title, double zoomLevel, PendingIntent pendingIntent, - Point... points) - { - final Request request = new Request() - .setTitle(title) - .setZoomLevel(zoomLevel) - .setPendingIntent(pendingIntent) - .setPoints(points); - sendRequest(caller, request); - } - - public static void pickPoint(Activity caller, String title, PendingIntent pi) - { - final Request request = new Request() - .setTitle(title) - .setPickPointMode(true) - .setPendingIntent(pi); - sendRequest(caller, request); - } - - /** - * Detects if Organic Maps is installed on the device. - * - * @param context - * @return - */ - public static boolean isOrganicMapsInstalled(Context context) - { - final Intent intent = new Intent(Const.ACTION_OM_REQUEST); - return context.getPackageManager().resolveActivity(intent, 0) != null; - } -} diff --git a/lib/src/main/java/app/organicmaps/api/Const.java b/lib/src/main/java/app/organicmaps/api/Const.java index f11991b..202c7d6 100644 --- a/lib/src/main/java/app/organicmaps/api/Const.java +++ b/lib/src/main/java/app/organicmaps/api/Const.java @@ -1,6 +1,5 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. - Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,37 +19,25 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ package app.organicmaps.api; public class Const { + // Common + static final String API_SCHEME = "om://"; + static final String AUTHORITY = "app.organicmaps.api"; + static final String EXTRA_PREFIX = AUTHORITY + ".extra"; - /* Request extras */ - static final String AUTHORITY = "com.mapswithme.maps.api"; - public static final String EXTRA_URL = AUTHORITY + ".url"; - public static final String EXTRA_TITLE = AUTHORITY + ".title"; - public static final String EXTRA_API_VERSION = AUTHORITY + ".version"; - public static final String EXTRA_CALLER_APP_INFO = AUTHORITY + ".caller_app_info"; - public static final String EXTRA_HAS_PENDING_INTENT = AUTHORITY + ".has_pen_intent"; - public static final String EXTRA_CALLER_PENDING_INTENT = AUTHORITY + ".pending_intent"; - public static final String EXTRA_RETURN_ON_BALLOON_CLICK = AUTHORITY + ".return_on_balloon_click"; - public static final String EXTRA_PICK_POINT = AUTHORITY + ".pick_point"; - public static final String EXTRA_CUSTOM_BUTTON_NAME = AUTHORITY + ".custom_button_name"; + // Request extras + public static final String EXTRA_PICK_POINT = EXTRA_PREFIX + ".PICK_POINT"; - - /* Response extras */ - /* Point part-by-part*/ - public static final String EXTRA_OM_RESPONSE_POINT_NAME = AUTHORITY + ".point_name"; - public static final String EXTRA_OM_RESPONSE_POINT_LAT = AUTHORITY + ".point_lat"; - public static final String EXTRA_OM_RESPONSE_POINT_LON = AUTHORITY + ".point_lon"; - public static final String EXTRA_OM_RESPONSE_POINT_ID = AUTHORITY + ".point_id"; - public static final String EXTRA_OM_RESPONSE_ZOOM = AUTHORITY + ".zoom_level"; - - - public static final String ACTION_OM_REQUEST = AUTHORITY + ".request"; - static final int API_VERSION = 2; - static final String CALLBACK_PREFIX = "mapswithme.client."; + // Response extras + public static final String EXTRA_POINT_NAME = EXTRA_PREFIX + ".POINT_NAME"; + public static final String EXTRA_POINT_LAT = EXTRA_PREFIX + ".POINT_LAT"; + public static final String EXTRA_POINT_LON = EXTRA_PREFIX + ".POINT_LON"; + public static final String EXTRA_POINT_ID = EXTRA_PREFIX + ".POINT_ID"; + public static final String EXTRA_ZOOM_LEVEL = EXTRA_PREFIX + ".ZOOM_LEVEL"; private Const() {} } diff --git a/lib/src/main/java/app/organicmaps/api/CrosshairRequest.java b/lib/src/main/java/app/organicmaps/api/CrosshairRequest.java new file mode 100644 index 0000000..2e3ecbb --- /dev/null +++ b/lib/src/main/java/app/organicmaps/api/CrosshairRequest.java @@ -0,0 +1,55 @@ +/* + Copyright (c) 2022, Organic Maps OÜ. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. Redistributions in binary form must + reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGE. + */ +package app.organicmaps.api; + +import android.content.Intent; +import android.net.Uri; + +import androidx.annotation.NonNull; + +public class CrosshairRequest +{ + private String mAppName; + + public CrosshairRequest setAppName(String appName) + { + mAppName = appName; + return this; + } + + public @NonNull + Intent toIntent() + { + final StringBuilder builder = new StringBuilder(Const.API_SCHEME); + builder.append("crosshair?"); + + // title + if (mAppName != null) + builder.append("appname").append("=").append(Uri.encode(mAppName)).append("&"); + + final Uri uri = Uri.parse(builder.toString()); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra(Const.EXTRA_PICK_POINT, true); + return intent; + } +} diff --git a/lib/src/main/java/app/organicmaps/api/DownloadDialog.java b/lib/src/main/java/app/organicmaps/api/DownloadDialog.java index 8e4fb5e..23d61f6 100644 --- a/lib/src/main/java/app/organicmaps/api/DownloadDialog.java +++ b/lib/src/main/java/app/organicmaps/api/DownloadDialog.java @@ -1,4 +1,4 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. @@ -20,7 +20,8 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ + package app.organicmaps.api; import android.app.Activity; diff --git a/lib/src/main/java/app/organicmaps/api/MapRequest.java b/lib/src/main/java/app/organicmaps/api/MapRequest.java new file mode 100644 index 0000000..676582d --- /dev/null +++ b/lib/src/main/java/app/organicmaps/api/MapRequest.java @@ -0,0 +1,111 @@ +/* + Copyright (c) 2022, Organic Maps OÜ. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. Redistributions in binary form must + reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGE. + */ +package app.organicmaps.api; + +import android.content.Intent; +import android.net.Uri; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +public class MapRequest +{ + private List mPoints = new ArrayList<>(); + private String mAppName; + private double mZoomLevel; + // pick point mode + private boolean mPickPointMode; + + public @NonNull MapRequest + setAppName(String appName) + { + mAppName = appName; + return this; + } + + public @NonNull + MapRequest addPoint(Point point) + { + mPoints.add(point); + return this; + } + + public @NonNull + MapRequest setPoints(Collection points) + { + mPoints = new ArrayList<>(points); + return this; + } + + public @NonNull + MapRequest setZoomLevel(double zoomLevel) + { + mZoomLevel = zoomLevel; + return this; + } + + public @NonNull MapRequest setPickPointMode(boolean pickPointMode) + { + mPickPointMode = pickPointMode; + return this; + } + + public @NonNull + Intent toIntent() + { + final StringBuilder builder = new StringBuilder(Const.API_SCHEME); + builder.append("map?"); + + // title + if (mAppName != null) + builder.append("appname").append("=").append(Uri.encode(mAppName)).append("&"); + // zoom + if (mZoomLevel != 0.0) + builder.append("z").append("=").append(mZoomLevel).append("&"); + + // points + for (final Point point : mPoints) + { + if (point != null) + { + builder.append("ll=").append(String.format(Locale.US, "%f,%f&", point.getLat(), point.getLon())); + if (point.getName() != null) + builder.append("n").append("=").append(Uri.encode(point.getName())).append("&"); + if (point.getId() != null) + builder.append("id").append("=").append(Uri.encode(point.getId())).append("&"); + if (point.getStyle() != null) + builder.append("s").append("=").append(Uri.encode(point.getStyle().getName())).append("&"); + } + } + + final Uri uri = Uri.parse(builder.toString()); + final Intent intent = new Intent(Intent.ACTION_VIEW, uri); + if (mPickPointMode) + intent.putExtra(Const.EXTRA_PICK_POINT, true); + return intent; + } +} diff --git a/lib/src/main/java/app/organicmaps/api/Response.java b/lib/src/main/java/app/organicmaps/api/PickPointResponse.java similarity index 50% rename from lib/src/main/java/app/organicmaps/api/Response.java rename to lib/src/main/java/app/organicmaps/api/PickPointResponse.java index 046b2eb..8d3058f 100644 --- a/lib/src/main/java/app/organicmaps/api/Response.java +++ b/lib/src/main/java/app/organicmaps/api/PickPointResponse.java @@ -1,6 +1,5 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. - Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,59 +19,57 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ package app.organicmaps.api; -import android.content.Context; import android.content.Intent; +import android.os.Bundle; -public class Response +public class PickPointResponse { - private final static double INVALID_LL = Double.MIN_VALUE; private Point mPoint; private double mZoomLevel; - private Response() {} + private PickPointResponse() {} /** - * Factory method to extract response data from intent. + * Factory method to extract response from intent. * - * @param context - * @param intent - * @return + * @param intent an intent to extra data from + * @return PointResponse */ - public static Response extractFromIntent(Context context, Intent intent) + public static PickPointResponse extractFromIntent(final Intent intent) { - final Response response = new Response(); - // parse point - final double lat = intent.getDoubleExtra(Const.EXTRA_OM_RESPONSE_POINT_LAT, INVALID_LL); - final double lon = intent.getDoubleExtra(Const.EXTRA_OM_RESPONSE_POINT_LON, INVALID_LL); - final String name = intent.getStringExtra(Const.EXTRA_OM_RESPONSE_POINT_NAME); - final String id = intent.getStringExtra(Const.EXTRA_OM_RESPONSE_POINT_ID); - - // parse additional info - response.mZoomLevel = intent.getDoubleExtra(Const.EXTRA_OM_RESPONSE_ZOOM, 9); - - if (lat != INVALID_LL && lon != INVALID_LL) - response.mPoint = new Point(lat, lon, name, id); - else - response.mPoint = null; - + final PickPointResponse response = new PickPointResponse(); + final Bundle extras = intent.getExtras(); + final double lat = extras.getDouble(Const.EXTRA_POINT_LAT); + final double lon = extras.getDouble(Const.EXTRA_POINT_LON); + final String name = extras.getString(Const.EXTRA_POINT_NAME); + final String id = extras.getString(Const.EXTRA_POINT_ID); + response.mPoint = new Point(lat, lon, name, id); + response.mZoomLevel = extras.getDouble(Const.EXTRA_ZOOM_LEVEL); return response; } /** - * @return point, for which user requested more information in Organic Maps application. + * @return selected point */ - public Point getPoint() {return mPoint;} + public Point getPoint() + { + return mPoint; + } - public boolean hasPoint() {return mPoint != null;} - - public double getZoomLevel() {return mZoomLevel;} + /** + * @return current zoom level + */ + public double getZoomLevel() + { + return mZoomLevel; + } @Override public String toString() { - return "Response [SelectedPoint=" + mPoint + "]"; + return "PointResponse [Point=" + mPoint + "]"; } } diff --git a/lib/src/main/java/app/organicmaps/api/Point.java b/lib/src/main/java/app/organicmaps/api/Point.java index 241a9f5..d5d6f62 100644 --- a/lib/src/main/java/app/organicmaps/api/Point.java +++ b/lib/src/main/java/app/organicmaps/api/Point.java @@ -1,4 +1,4 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. @@ -20,10 +20,13 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ package app.organicmaps.api; +import androidx.annotation.NonNull; + import java.io.Serializable; +import java.util.Objects; /** * POI wrapper object. @@ -53,15 +56,6 @@ public final class Point implements Serializable this.mId = id; } - public Point(double lat, double lon, String name, String id, Style style) - { - this.mLat = lat; - this.mLon = lon; - this.mName = name; - this.mId = id; - this.mStyle = style; - } - public double getLat() {return mLat;} public double getLon() {return mLon;} @@ -74,7 +68,7 @@ public final class Point implements Serializable * Sets string ID for this point. Internally it is not used to distinguish point, * it's purpose to help clients code to associate point with domain objects of their application. * - * @param id + * @param id point id */ public void setId(String id) {mId = id;} @@ -90,9 +84,8 @@ public final class Point implements Serializable this.mStyle = style; } - public String getStyleForUrl() {return (mStyle == null) ? null : mStyle.getName();} - @Override + @NonNull public String toString() { return "OMPoint [lat=" + mLat + @@ -135,9 +128,10 @@ public final class Point implements Serializable if (Double.doubleToLongBits(mLon) != Double.doubleToLongBits(other.mLon)) return false; - return mName == null ? other.mName == null : mName.equals(other.mName); + return Objects.equals(mName, other.mName); } + /** * Supported styles for Organic Maps. Each appears as a small flag of the appropriate colour. */ @@ -171,7 +165,7 @@ public final class Point implements Serializable /** * @return name as it should appear in the MAPS.ME URL. */ - private String getName() + public String getName() { return name; } diff --git a/lib/src/main/java/app/organicmaps/api/Request.java b/lib/src/main/java/app/organicmaps/api/Request.java deleted file mode 100644 index 1a006f9..0000000 --- a/lib/src/main/java/app/organicmaps/api/Request.java +++ /dev/null @@ -1,194 +0,0 @@ -/****************************************************************************** - Copyright (c) 2022, Organic Maps OÜ. All rights reserved. - Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. Redistributions in binary form must - reproduce the above copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with the - distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. - ******************************************************************************/ -package app.organicmaps.api; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Locale; - -public class Request -{ - - // ** - private List mPoints = new ArrayList<>(); - private PendingIntent mPendingIntent; - private String mTitle; - private double mZoomLevel = 1; - private boolean mReturnOnBalloonClick; - private boolean mPickPoint = false; - private String mCustomButtonName = ""; - // ** - - private static StringBuilder createMwmUrl(Context context, String title, double zoomLevel, List points) - { - final StringBuilder urlBuilder = new StringBuilder("om://map?"); - // version - urlBuilder.append("v=").append(Const.API_VERSION).append("&"); - // back url, always not null - urlBuilder.append("backurl=").append(getCallbackAction(context)).append("&"); - // title - appendIfNotNull(urlBuilder, "appname", title); - // zoom - appendIfNotNull(urlBuilder, "z", isValidZoomLevel(zoomLevel) ? String.valueOf(zoomLevel) : null); - - // points - for (final Point point : points) - { - if (point != null) - { - urlBuilder.append("ll=").append(String.format(Locale.US, "%f,%f&", point.getLat(), point.getLon())); - - appendIfNotNull(urlBuilder, "n", point.getName()); - appendIfNotNull(urlBuilder, "id", point.getId()); - appendIfNotNull(urlBuilder, "s", point.getStyleForUrl()); - } - } - - return urlBuilder; - } - - private static String getCallbackAction(Context context) - { - return Const.CALLBACK_PREFIX + context.getPackageName(); - } - - private static Intent addCommonExtras(Context context, Intent intent) - { - intent.putExtra(Const.EXTRA_CALLER_APP_INFO, context.getApplicationInfo()); - intent.putExtra(Const.EXTRA_API_VERSION, Const.API_VERSION); - - return intent; - } - - private static StringBuilder appendIfNotNull(StringBuilder builder, String key, String value) - { - if (value != null) - builder.append(key).append("=").append(Uri.encode(value)).append("&"); - - return builder; - } - - private static boolean isValidZoomLevel(double zoom) - { - return zoom >= Api.ZOOM_MIN && zoom <= Api.ZOOM_MAX; - } - - public Request setCustomButtonName(String buttonName) - { - mCustomButtonName = buttonName != null ? buttonName : ""; - return this; - } - - public Request setTitle(String title) - { - mTitle = title; - return this; - } - - public Request setPickPointMode(boolean pickPoint) - { - mPickPoint = pickPoint; - return this; - } - - public Request addPoint(Point point) - { - mPoints.add(point); - return this; - } - - public Request addPoint(double lat, double lon, String name, String id) - { - return addPoint(new Point(lat, lon, name, id)); - } - - public Request setPoints(Collection points) - { - mPoints = new ArrayList(points); - return this; - } - - // Below are utilities from OrganicMapsApi because we are not "Feature Envy" - - public Request setReturnOnBalloonClick(boolean doReturn) - { - mReturnOnBalloonClick = doReturn; - return this; - } - - public Request setZoomLevel(double zoomLevel) - { - mZoomLevel = zoomLevel; - return this; - } - - public Request setPendingIntent(PendingIntent pi) - { - mPendingIntent = pi; - return this; - } - - public Intent toIntent(Context context) - { - final Intent mwmIntent = new Intent(Const.ACTION_OM_REQUEST); - - // url - final String mwmUrl = createMwmUrl(context, mTitle, mZoomLevel, mPoints).toString(); - mwmIntent.putExtra(Const.EXTRA_URL, mwmUrl); - // title - mwmIntent.putExtra(Const.EXTRA_TITLE, mTitle); - // more - mwmIntent.putExtra(Const.EXTRA_RETURN_ON_BALLOON_CLICK, mReturnOnBalloonClick); - // pick point - mwmIntent.putExtra(Const.EXTRA_PICK_POINT, mPickPoint); - // custom button name - mwmIntent.putExtra(Const.EXTRA_CUSTOM_BUTTON_NAME, mCustomButtonName); - - final boolean hasIntent = mPendingIntent != null; - mwmIntent.putExtra(Const.EXTRA_HAS_PENDING_INTENT, hasIntent); - if (hasIntent) - mwmIntent.putExtra(Const.EXTRA_CALLER_PENDING_INTENT, mPendingIntent); - - addCommonExtras(context, mwmIntent); - - return mwmIntent; - } - - /** - * @Hidden This method is internal only. - * Used for compatibility. - */ - Request setPoints(Point[] points) - { - return setPoints(Arrays.asList(points)); - } - -} diff --git a/sample-app-capitals/build.gradle b/sample-app-capitals/build.gradle index e17af69..71f05a8 100644 --- a/sample-app-capitals/build.gradle +++ b/sample-app-capitals/build.gradle @@ -11,8 +11,6 @@ android { targetSdk 32 versionCode 1 versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CapitalsListActivity.java b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CapitalsListActivity.java index b1fcf58..2e1ee3f 100644 --- a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CapitalsListActivity.java +++ b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CapitalsListActivity.java @@ -1,4 +1,4 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. @@ -20,24 +20,28 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -******************************************************************************/ + */ package app.organicmaps.api.sample.capitals; import android.app.ListActivity; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import app.organicmaps.api.Point; -import app.organicmaps.api.Api; +import app.organicmaps.api.MapRequest; + +import java.util.ArrayList; public class CapitalsListActivity extends ListActivity { + private static final int REQ_CODE_CITY = 1; + CityAdapter mCityAdapter; @Override @@ -61,12 +65,27 @@ public class CapitalsListActivity extends ListActivity private void showCityOnOMMap(City ... cities) { - Point[] points = new Point[cities.length]; + ArrayList points = new ArrayList<>(cities.length); for (int i = 0; i < cities.length; i++) - points[i] = cities[i].toPoint(); + points.add(cities[i].toPoint()); final String title = cities.length == 1 ? cities[0].getName() : "Capitals of the World"; - Api.showPointsOnMap(this, title, CityDetailsActivity.getPendingIntent(this), points); + final Intent intent = new MapRequest() + .setPoints(points) + .setAppName(title) + .toIntent(); + this.startActivityForResult(intent, REQ_CODE_CITY); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) + { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode != REQ_CODE_CITY || resultCode != RESULT_OK) + return; + + Intent intent = new Intent(this, CityDetailsActivity.class); + intent.putExtra(CityDetailsActivity.EXTRA_POINT, data); } private static class CityAdapter extends ArrayAdapter diff --git a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/City.java b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/City.java index d491fb5..0e612eb 100644 --- a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/City.java +++ b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/City.java @@ -1,4 +1,4 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. @@ -20,7 +20,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ package app.organicmaps.api.sample.capitals; import app.organicmaps.api.Point; diff --git a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CityDetailsActivity.java b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CityDetailsActivity.java index c3fe059..528675e 100644 --- a/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CityDetailsActivity.java +++ b/sample-app-capitals/src/main/java/app/organicmaps/api/sample/capitals/CityDetailsActivity.java @@ -1,4 +1,4 @@ -/****************************************************************************** +/* Copyright (c) 2022, Organic Maps OÜ. All rights reserved. Copyright (c) 2013, MapsWithMe GmbH. All rights reserved. @@ -20,25 +20,24 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ + */ package app.organicmaps.api.sample.capitals; import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; import android.widget.TextView; -import app.organicmaps.api.Response; -import app.organicmaps.api.Api; +import androidx.annotation.NonNull; + +import app.organicmaps.api.PickPointResponse; +import app.organicmaps.api.Point; +import app.organicmaps.api.MapRequest; public class CityDetailsActivity extends Activity { - public static String EXTRA_FROM_ORGANICMAPS = "from-organicmaps"; - + private static final int REQ_CODE_CITY = 1; + public static String EXTRA_POINT = "point"; private TextView mName; private TextView mAltNames; private TextView mCountry; @@ -52,13 +51,6 @@ public class CityDetailsActivity extends Activity private City mCity; - public static PendingIntent getPendingIntent(Context context) - { - final Intent i = new Intent(context, CityDetailsActivity.class); - i.putExtra(EXTRA_FROM_ORGANICMAPS, true); - return PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_IMMUTABLE); - } - @Override protected void onCreate(Bundle savedInstanceState) { @@ -76,48 +68,48 @@ public class CityDetailsActivity extends Activity mPopulation = (TextView) findViewById(R.id.population); mTimeZone = (TextView) findViewById(R.id.timeZone); - findViewById(R.id.showOnMap).setOnClickListener(new OnClickListener() - { - @Override - public void onClick(View v) - { - Api.showPointsOnMap(CityDetailsActivity.this,mCity.getName(), - CityDetailsActivity.getPendingIntent(CityDetailsActivity.this),mCity.toPoint()); - } + findViewById(R.id.showOnMap).setOnClickListener(v -> { + final Intent intent = new MapRequest() + .addPoint(mCity.toPoint()) + .setAppName(getString(R.string.app_name)) + .toIntent(); + startActivityForResult(intent, REQ_CODE_CITY); }); - handleIntent(getIntent()); + final Intent data = getIntent().getParcelableExtra(EXTRA_POINT); + handleResponse(data); + } + + private void handleResponse(final @NonNull Intent data) + { + final PickPointResponse response = PickPointResponse.extractFromIntent(data); + final Point point = response.getPoint(); + mCity = City.fromPoint(point); + + if (mCity != null) + { + mName.setText(mCity.getName()); + mAltNames.setText(mCity.getAltNames()); + mCountry.setText(mCity.getCountryCode()); + + mLat.setText(mCity.getLat() + ""); + mLon.setText(mCity.getLon() + ""); + final String evel = mCity.getElevation() != -9999 ? String.valueOf(mCity.getElevation()) : "No Data"; + mElev.setText(evel); + + final String popul = mCity.getPopulation() != -1 ? String.valueOf(mCity.getPopulation()) : "No Data"; + mPopulation.setText(popul); + mTimeZone.setText(mCity.getTimeZone()); + } } @Override - protected void onNewIntent(Intent intent) + protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onNewIntent(intent); - handleIntent(intent); + super.onActivityResult(requestCode, resultCode, data); + if (requestCode != REQ_CODE_CITY || resultCode != RESULT_OK) + return; + + handleResponse(data); } - - private void handleIntent(Intent intent) - { - if (intent.getBooleanExtra(EXTRA_FROM_ORGANICMAPS, false)) - { - final Response response = Response.extractFromIntent(this, intent); - mCity = City.fromPoint(response.getPoint()); - - if (mCity != null) - { - mName.setText(mCity.getName()); - mAltNames.setText(mCity.getAltNames()); - mCountry.setText(mCity.getCountryCode()); - - mLat.setText(mCity.getLat() + ""); - mLon.setText(mCity.getLon() + ""); - final String evel = mCity.getElevation() != -9999 ? String.valueOf(mCity.getElevation()) : "No Data"; - mElev.setText(evel); - - final String popul = mCity.getPopulation() != -1 ? String.valueOf(mCity.getPopulation()) : "No Data"; - mPopulation.setText(popul); - mTimeZone.setText(mCity.getTimeZone()); - } - } - } -} +} \ No newline at end of file diff --git a/sample-app-capitals/src/main/res/values/strings.xml b/sample-app-capitals/src/main/res/values/strings.xml index 867894a..d5b9d65 100644 --- a/sample-app-capitals/src/main/res/values/strings.xml +++ b/sample-app-capitals/src/main/res/values/strings.xml @@ -12,5 +12,6 @@ Population: Time Zone: Elevation: + Cancelled diff --git a/sample-pick-point/.gitignore b/sample-pick-point/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/sample-pick-point/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/sample-pick-point/build.gradle b/sample-pick-point/build.gradle new file mode 100644 index 0000000..8ca2fda --- /dev/null +++ b/sample-pick-point/build.gradle @@ -0,0 +1,31 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "app.organicmaps.api.sample.pick_point" + minSdk 21 + targetSdk 32 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation 'com.google.android.material:material:1.6.1' + implementation project(path: ':lib') +} \ No newline at end of file diff --git a/sample-pick-point/proguard-rules.pro b/sample-pick-point/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/sample-pick-point/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/sample-pick-point/src/main/AndroidManifest.xml b/sample-pick-point/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a322646 --- /dev/null +++ b/sample-pick-point/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/sample-pick-point/src/main/java/app/organicmaps/api/sample/pick_point/MainActivity.java b/sample-pick-point/src/main/java/app/organicmaps/api/sample/pick_point/MainActivity.java new file mode 100644 index 0000000..90e87bf --- /dev/null +++ b/sample-pick-point/src/main/java/app/organicmaps/api/sample/pick_point/MainActivity.java @@ -0,0 +1,60 @@ +package app.organicmaps.api.sample.pick_point; + +import android.content.Intent; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.AppCompatActivity; + +import app.organicmaps.api.CrosshairRequest; +import app.organicmaps.api.DownloadDialog; +import app.organicmaps.api.PickPointResponse; +import app.organicmaps.api.Point; + +public class MainActivity extends AppCompatActivity +{ + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + final ActivityResultLauncher pickPoint = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> onPointSelected(result.getResultCode(), result.getData())); + + + findViewById(R.id.pick_point).setOnClickListener(v -> { + final Intent request = new CrosshairRequest().setAppName(getString(R.string.app_name)) + .toIntent(); + if (getApplicationContext().getPackageManager().resolveActivity(request, 0) == null) + { + new DownloadDialog(this).show(); + return; + } + + pickPoint.launch(request); + }); + } + + protected void onPointSelected(int resultCode, Intent data) + { + if (resultCode == RESULT_CANCELED) + { + Toast.makeText(this, getString(R.string.cancelled), Toast.LENGTH_LONG).show(); + return; + } + else if (resultCode != RESULT_OK) + { + throw new AssertionError("Unsupported resultCode: " + resultCode); + } + + final PickPointResponse response = PickPointResponse.extractFromIntent(data); + final Point point = response.getPoint(); + + final String message = getString(R.string.result, point.getLat(), point.getLon(), point.getId(), point.getName(), response.getZoomLevel()); + Toast.makeText(this, message, Toast.LENGTH_LONG).show(); + } +} \ No newline at end of file diff --git a/sample-pick-point/src/main/res/drawable-v24/ic_launcher_foreground.xml b/sample-pick-point/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..3990a15 --- /dev/null +++ b/sample-pick-point/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sample-pick-point/src/main/res/drawable/ic_launcher_background.xml b/sample-pick-point/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..61bb79e --- /dev/null +++ b/sample-pick-point/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sample-pick-point/src/main/res/layout/activity_main.xml b/sample-pick-point/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ed39287 --- /dev/null +++ b/sample-pick-point/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ + + + +