diff --git a/lib/src/com/mapswithme/maps/api/Const.java b/lib/src/com/mapswithme/maps/api/Const.java index 4f6664c..3393e47 100644 --- a/lib/src/com/mapswithme/maps/api/Const.java +++ b/lib/src/com/mapswithme/maps/api/Const.java @@ -33,6 +33,7 @@ public class Const 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"; /* Response extras */ @@ -44,7 +45,7 @@ public class Const public static final String ACTION_MWM_REQUEST = AUTHORITY + ".request"; - static final int API_VERSION = 1; + static final int API_VERSION = 2; static final String CALLBACK_PREFIX = "mapswithme.client."; private Const() {} diff --git a/lib/src/com/mapswithme/maps/api/MapsWithMeApi.java b/lib/src/com/mapswithme/maps/api/MapsWithMeApi.java index 615fbbb..0600628 100644 --- a/lib/src/com/mapswithme/maps/api/MapsWithMeApi.java +++ b/lib/src/com/mapswithme/maps/api/MapsWithMeApi.java @@ -19,18 +19,17 @@ 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 com.mapswithme.maps.api; -import java.util.Locale; - -import android.annotation.SuppressLint; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.net.Uri; + + public final class MapsWithMeApi { @@ -44,89 +43,21 @@ public final class MapsWithMeApi public static final double ZOOM_MIN = 1; - /** - * 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) + public static void showMapsWithMeUrl(Activity caller, PendingIntent pendingIntent, double zoomLevel, String url) { - showPointsOnMap(caller, (String)null, (PendingIntent)null, new MWMPoint(lat, lon, name)); + 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 MWMPoint(lat, lon, name, id)); } - - /** - * Shows single point on the map using specified - * zoom level in range from {@link MapsWithMeApi#ZOOM_MIN} to {@link MapsWithMeApi#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) + public static void sendRequest(Activity caller, MwmRequest request) { - showPointsOnMap(caller, (String)null, zoomLevel, (PendingIntent)null, new MWMPoint(lat, lon, name)); - } - - /** - * Shows set of points on the map. - * - * @param caller - * @param title - * @param points - */ - public static void showPointsOnMap(Activity caller, String title, MWMPoint... points) - { - showPointsOnMap(caller, title, null, points); - } - - /** - * Shows set of points on the maps - * and allows MapsWithMeApplication 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, MWMPoint ... points) - { - showPointsOnMap(caller, title, -1, pendingIntent, points); - } - - /** - * Detects if any version (Lite, Pro) of MapsWithMe, which supports - * API calls are installed on the device. - * - * @param context - * @return - */ - public static boolean isMapsWithMeInstalled(Context context) - { - final Intent intent = new Intent(Const.ACTION_MWM_REQUEST); - return context.getPackageManager().resolveActivity(intent, 0) != null; - } - - // Internal only code - - private static void showPointsOnMap(Activity caller, String title, double zoomLevel, PendingIntent pendingIntent, MWMPoint... points) - { - final Intent mwmIntent = new Intent(Const.ACTION_MWM_REQUEST); - - mwmIntent.putExtra(Const.EXTRA_URL, createMwmUrl(caller, title, zoomLevel, points).toString()); - mwmIntent.putExtra(Const.EXTRA_TITLE, title); - - final boolean hasIntent = pendingIntent != null; - mwmIntent.putExtra(Const.EXTRA_HAS_PENDING_INTENT, hasIntent); - if (hasIntent) - mwmIntent.putExtra(Const.EXTRA_CALLER_PENDING_INTENT, pendingIntent); - - addCommonExtras(caller, mwmIntent); + final Intent mwmIntent = request.toIntent(caller); if (isMapsWithMeInstalled(caller)) { @@ -139,65 +70,81 @@ public final class MapsWithMeApi (new DownloadMapsWithMeDialog(caller)).show(); } - static StringBuilder createMwmUrl(Context context, String title, double zoomLevel, MWMPoint ... points) + /** + * 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) { - StringBuilder urlBuilder = new StringBuilder("mapswithme://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 (MWMPoint 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()); - } - } - - return urlBuilder; + showPointsOnMap(caller, (String) null, (PendingIntent) null, new MWMPoint(lat, lon, name)); } - static String getCallbackAction(Context context) + /** + * Shows single point on the map using specified zoom level in range from + * {@link MapsWithMeApi#ZOOM_MIN} to {@link MapsWithMeApi#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) { - return Const.CALLBACK_PREFIX + context.getPackageName(); + showPointsOnMap(caller, (String) null, zoomLevel, (PendingIntent) null, new MWMPoint(lat, lon, name)); } - @SuppressLint("NewApi") - private static Intent addCommonExtras(Context context, Intent intent) + /** + * Shows set of points on the map. + * + * @param caller + * @param title + * @param points + */ + public static void showPointsOnMap(Activity caller, String title, MWMPoint... points) { - intent.putExtra(Const.EXTRA_CALLER_APP_INFO, context.getApplicationInfo()); - intent.putExtra(Const.EXTRA_API_VERSION, Const.API_VERSION); - - return intent; + showPointsOnMap(caller, title, null, points); } - private static StringBuilder appendIfNotNull(StringBuilder builder, String key, String value) + /** + * Shows set of points on the maps and allows MapsWithMeApplication 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, MWMPoint... points) { - if (value != null) - builder.append(key) - .append("=") - .append(Uri.encode(value)) - .append("&"); - - return builder; + showPointsOnMap(caller, title, -1, pendingIntent, points); } - private static boolean isValidZoomLevel(double zoom) + private static void showPointsOnMap(Activity caller, String title, double zoomLevel, PendingIntent pendingIntent, + MWMPoint... points) { - return zoom >= ZOOM_MIN && zoom <= ZOOM_MAX; + final MwmRequest request = new MwmRequest() + .setTitle(title) + .setZoomLevel(zoomLevel) + .setPendingIntent(pendingIntent) + .setPoints(points); + sendRequest(caller, request); + } + + /** + * Detects if any version (Lite, Pro) of MapsWithMe, which supports API calls + * are installed on the device. + * + * @param context + * @return + */ + public static boolean isMapsWithMeInstalled(Context context) + { + final Intent intent = new Intent(Const.ACTION_MWM_REQUEST); + return context.getPackageManager().resolveActivity(intent, 0) != null; } } diff --git a/lib/src/com/mapswithme/maps/api/MwmRequest.java b/lib/src/com/mapswithme/maps/api/MwmRequest.java new file mode 100644 index 0000000..61e53b6 --- /dev/null +++ b/lib/src/com/mapswithme/maps/api/MwmRequest.java @@ -0,0 +1,155 @@ +package com.mapswithme.maps.api; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import android.annotation.SuppressLint; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + +public class MwmRequest +{ + + // ** + private List mPoints = new ArrayList(); + private PendingIntent mPendingIntent; + private String mTitle; + private double mZoomLevel = 1; + private boolean mReturnOnBalloonClick; + // ** + + public MwmRequest setTitle(String title) + { + mTitle = title; + return this; + } + + public MwmRequest addPoint(MWMPoint point) + { + mPoints.add(point); + return this; + } + + public MwmRequest addPoint(double lat, double lon, String name, String id) + { + return addPoint(new MWMPoint(lat, lon, name, id)); + } + + public MwmRequest setPoints(Collection points) + { + mPoints = new ArrayList(points); + return this; + } + + public MwmRequest setReturnOnBalloonClick(boolean doReturn) + { + mReturnOnBalloonClick = doReturn; + return this; + } + + public MwmRequest setZoomLevel(double zoomLevel) + { + mZoomLevel = zoomLevel; + return this; + } + + public MwmRequest setPendingIntent(PendingIntent pi) + { + mPendingIntent = pi; + return this; + } + + public Intent toIntent(Context context) + { + final Intent mwmIntent = new Intent(Const.ACTION_MWM_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); + + 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. + */ + MwmRequest setPoints(MWMPoint[] points) + { + return setPoints(Arrays.asList(points)); + } + + // Below are utilities from MapsWithMeApi because we are not "Feature Envy" + + private static StringBuilder createMwmUrl(Context context, String title, double zoomLevel, List points) + { + final StringBuilder urlBuilder = new StringBuilder("mapswithme://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 MWMPoint 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()); + } + } + + return urlBuilder; + } + + private static String getCallbackAction(Context context) + { + return Const.CALLBACK_PREFIX + context.getPackageName(); + } + + @SuppressLint("NewApi") + 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 >= MapsWithMeApi.ZOOM_MIN && zoom <= MapsWithMeApi.ZOOM_MAX; + } + +}