1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.incallui.calllocation.impl;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.res.Resources;
22 import android.location.Location;
23 import android.net.Uri;
24 import android.support.annotation.Nullable;
25 import android.support.annotation.VisibleForTesting;
26 import java.util.Locale;
27 
28 class LocationUrlBuilder {
29 
30   // Static Map API path constants.
31   private static final String HTTPS_SCHEME = "https";
32   private static final String MAPS_API_DOMAIN = "maps.googleapis.com";
33   private static final String MAPS_PATH = "maps";
34   private static final String API_PATH = "api";
35   private static final String STATIC_MAP_PATH = "staticmap";
36   private static final String GEOCODE_PATH = "geocode";
37   private static final String GEOCODE_OUTPUT_TYPE = "json";
38 
39   // Static Map API parameter constants.
40   private static final String KEY_PARAM_KEY = "key";
41   private static final String CENTER_PARAM_KEY = "center";
42   private static final String ZOOM_PARAM_KEY = "zoom";
43   private static final String SCALE_PARAM_KEY = "scale";
44   private static final String SIZE_PARAM_KEY = "size";
45   private static final String MARKERS_PARAM_KEY = "markers";
46 
47   private static final String ZOOM_PARAM_VALUE = Integer.toString(16);
48 
49   private static final String LAT_LONG_DELIMITER = ",";
50 
51   private static final String MARKER_DELIMITER = "|";
52   private static final String MARKER_STYLE_DELIMITER = ":";
53   private static final String MARKER_STYLE_COLOR = "color";
54   private static final String MARKER_STYLE_COLOR_RED = "red";
55 
56   private static final String LAT_LNG_PARAM_KEY = "latlng";
57 
58   private static final String ANDROID_API_KEY_VALUE = "AIzaSyAXdDnif6B7sBYxU8hzw9qAp3pRPVHs060";
59   private static final String BROWSER_API_KEY_VALUE = "AIzaSyBfLlvWYndiQ3RFEHli65qGQH36QIxdyCI";
60 
61   /**
62    * Generates the URL to a static map image for the given location.
63    *
64    * <p>This image has the following characteristics:
65    *
66    * <p>- It is centered at the given latitude and longitutde. - It is scaled according to the
67    * device's pixel density. - There is a red marker at the given latitude and longitude.
68    *
69    * <p>Source: https://developers.google.com/maps/documentation/staticmaps/
70    *
71    * @param contxt The context.
72    * @param Location A location.
73    * @return The URL of a static map image url of the given location.
74    */
getStaticMapUrl(Context context, Location location)75   public static String getStaticMapUrl(Context context, Location location) {
76     final Uri.Builder builder = new Uri.Builder();
77     Resources res = context.getResources();
78     String size =
79         res.getDimensionPixelSize(R.dimen.location_map_width)
80             + "x"
81             + res.getDimensionPixelSize(R.dimen.location_map_height);
82 
83     builder
84         .scheme(HTTPS_SCHEME)
85         .authority(MAPS_API_DOMAIN)
86         .appendPath(MAPS_PATH)
87         .appendPath(API_PATH)
88         .appendPath(STATIC_MAP_PATH)
89         .appendQueryParameter(CENTER_PARAM_KEY, getFormattedLatLng(location))
90         .appendQueryParameter(ZOOM_PARAM_KEY, ZOOM_PARAM_VALUE)
91         .appendQueryParameter(SIZE_PARAM_KEY, size)
92         .appendQueryParameter(SCALE_PARAM_KEY, Float.toString(res.getDisplayMetrics().density))
93         .appendQueryParameter(MARKERS_PARAM_KEY, getMarkerUrlParamValue(location))
94         .appendQueryParameter(KEY_PARAM_KEY, ANDROID_API_KEY_VALUE);
95 
96     return builder.build().toString();
97   }
98 
99   /**
100    * Generates the URL for a request to reverse geocode the given location.
101    *
102    * <p>Source: https://developers.google.com/maps/documentation/geocoding/#ReverseGeocoding
103    *
104    * @param Location A location.
105    */
getReverseGeocodeUrl(Location location)106   public static String getReverseGeocodeUrl(Location location) {
107     final Uri.Builder builder = new Uri.Builder();
108 
109     builder
110         .scheme(HTTPS_SCHEME)
111         .authority(MAPS_API_DOMAIN)
112         .appendPath(MAPS_PATH)
113         .appendPath(API_PATH)
114         .appendPath(GEOCODE_PATH)
115         .appendPath(GEOCODE_OUTPUT_TYPE)
116         .appendQueryParameter(LAT_LNG_PARAM_KEY, getFormattedLatLng(location))
117         .appendQueryParameter(KEY_PARAM_KEY, BROWSER_API_KEY_VALUE);
118 
119     return builder.build().toString();
120   }
121 
getShowMapIntent( Location location, @Nullable CharSequence addressLine1, @Nullable CharSequence addressLine2)122   public static Intent getShowMapIntent(
123       Location location, @Nullable CharSequence addressLine1, @Nullable CharSequence addressLine2) {
124 
125     String latLong = getFormattedLatLng(location);
126     String url = String.format(Locale.US, "geo: %s?q=%s", latLong, latLong);
127 
128     // Add a map label
129     if (addressLine1 != null) {
130       if (addressLine2 != null) {
131         url +=
132             String.format(Locale.US, "(%s, %s)", addressLine1.toString(), addressLine2.toString());
133       } else {
134         url += String.format(Locale.US, "(%s)", addressLine1.toString());
135       }
136     } else {
137       // TODO(mdooley): i18n
138       url +=
139           String.format(
140               Locale.US,
141               "(Latitude: %f, Longitude: %f)",
142               location.getLatitude(),
143               location.getLongitude());
144     }
145 
146     Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
147     intent.setPackage("com.google.android.apps.maps");
148     return intent;
149   }
150 
151   /**
152    * Returns a comma-separated latitude and longitude pair, formatted for use as a URL parameter
153    * value.
154    *
155    * @param location A location.
156    * @return The comma-separated latitude and longitude pair of that location.
157    */
158   @VisibleForTesting
getFormattedLatLng(Location location)159   static String getFormattedLatLng(Location location) {
160     return location.getLatitude() + LAT_LONG_DELIMITER + location.getLongitude();
161   }
162 
163   /**
164    * Returns the URL parameter value for the marker, specifying its style and position.
165    *
166    * @param location A location.
167    * @return The URL parameter value for the marker.
168    */
169   @VisibleForTesting
getMarkerUrlParamValue(Location location)170   static String getMarkerUrlParamValue(Location location) {
171     return MARKER_STYLE_COLOR
172         + MARKER_STYLE_DELIMITER
173         + MARKER_STYLE_COLOR_RED
174         + MARKER_DELIMITER
175         + getFormattedLatLng(location);
176   }
177 }
178