blob: ac7eb8b18e9739b6b4985574ee8aab955f98a6e8 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
2 * Copyright (C) 2007 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
17package android.location;
18
19import android.content.Context;
20import android.location.Address;
21import android.os.RemoteException;
22import android.os.IBinder;
23import android.os.ServiceManager;
24import android.util.Log;
25
26import java.io.IOException;
27import java.util.Locale;
28import java.util.ArrayList;
29import java.util.List;
30
31/**
32 * A class for handling geocoding and reverse geocoding. Geocoding is
33 * the process of transforming a street address or other description
34 * of a location into a (latitude, longitude) coordinate. Reverse
35 * geocoding is the process of transforming a (latitude, longitude)
36 * coordinate into a (partial) address. The amount of detail in a
37 * reverse geocoded location description may vary, for example one
38 * might contain the full street address of the closest building, while
39 * another might contain only a city name and postal code.
40 *
41 * The Geocoder class requires a backend service that is not included in
42 * the core android framework. The Geocoder query methods will return an
43 * empty list if there no backend service in the platform. Use the
44 * isPresent() method to determine whether a Geocoder implementation
45 * exists.
46 */
47public final class Geocoder {
48 private static final String TAG = "Geocoder";
49
50 private GeocoderParams mParams;
51 private ILocationManager mService;
52
53 /**
54 * Returns true if the Geocoder methods getFromLocation and
55 * getFromLocationName are implemented. Lack of network
56 * connectivity may still cause these methods to return null or
57 * empty lists.
58 */
59 public static boolean isPresent() {
60 IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
61 ILocationManager lm = ILocationManager.Stub.asInterface(b);
62 try {
63 return lm.geocoderIsPresent();
64 } catch (RemoteException e) {
65 Log.e(TAG, "isPresent: got RemoteException", e);
66 return false;
67 }
68 }
69
70 /**
71 * Constructs a Geocoder whose responses will be localized for the
72 * given Locale.
73 *
74 * @param context the Context of the calling Activity
75 * @param locale the desired Locale for the query results
76 *
77 * @throws NullPointerException if Locale is null
78 */
79 public Geocoder(Context context, Locale locale) {
80 if (locale == null) {
81 throw new NullPointerException("locale == null");
82 }
83 mParams = new GeocoderParams(context, locale);
84 IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
85 mService = ILocationManager.Stub.asInterface(b);
86 }
87
88 /**
89 * Constructs a Geocoder whose responses will be localized for the
90 * default system Locale.
91 *
92 * @param context the Context of the calling Activity
93 */
94 public Geocoder(Context context) {
95 this(context, Locale.getDefault());
96 }
97
98 /**
99 * Returns an array of Addresses that are known to describe the
100 * area immediately surrounding the given latitude and longitude.
101 * The returned addresses will be localized for the locale
102 * provided to this class's constructor.
103 *
104 * <p> The returned values may be obtained by means of a network lookup.
105 * The results are a best guess and are not guaranteed to be meaningful or
106 * correct. It may be useful to call this method from a thread separate from your
107 * primary UI thread.
108 *
109 * @param latitude the latitude a point for the search
110 * @param longitude the longitude a point for the search
111 * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
112 *
113 * @return a list of Address objects. Returns null or empty list if no matches were
114 * found or there is no backend service available.
115 *
116 * @throws IllegalArgumentException if latitude is
117 * less than -90 or greater than 90
118 * @throws IllegalArgumentException if longitude is
119 * less than -180 or greater than 180
120 * @throws IOException if the network is unavailable or any other
121 * I/O problem occurs
122 */
123 public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
124 throws IOException {
125 if (latitude < -90.0 || latitude > 90.0) {
126 throw new IllegalArgumentException("latitude == " + latitude);
127 }
128 if (longitude < -180.0 || longitude > 180.0) {
129 throw new IllegalArgumentException("longitude == " + longitude);
130 }
131 try {
132 List<Address> results = new ArrayList<Address>();
133 String ex = mService.getFromLocation(latitude, longitude, maxResults,
134 mParams, results);
135 if (ex != null) {
136 throw new IOException(ex);
137 } else {
138 return results;
139 }
140 } catch (RemoteException e) {
141 Log.e(TAG, "getFromLocation: got RemoteException", e);
142 return null;
143 }
144 }
145
146 /**
147 * Returns an array of Addresses that are known to describe the
148 * named location, which may be a place name such as "Dalvik,
149 * Iceland", an address such as "1600 Amphitheatre Parkway,
150 * Mountain View, CA", an airport code such as "SFO", etc.. The
151 * returned addresses will be localized for the locale provided to
152 * this class's constructor.
153 *
154 * <p> The query will block and returned values will be obtained by means of a network lookup.
155 * The results are a best guess and are not guaranteed to be meaningful or
156 * correct. It may be useful to call this method from a thread separate from your
157 * primary UI thread.
158 *
159 * @param locationName a user-supplied description of a location
160 * @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended
161 *
162 * @return a list of Address objects. Returns null or empty list if no matches were
163 * found or there is no backend service available.
164 *
165 * @throws IllegalArgumentException if locationName is null
166 * @throws IOException if the network is unavailable or any other
167 * I/O problem occurs
168 */
169 public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
170 if (locationName == null) {
171 throw new IllegalArgumentException("locationName == null");
172 }
173 try {
174 List<Address> results = new ArrayList<Address>();
175 String ex = mService.getFromLocationName(locationName,
176 0, 0, 0, 0, maxResults, mParams, results);
177 if (ex != null) {
178 throw new IOException(ex);
179 } else {
180 return results;
181 }
182 } catch (RemoteException e) {
183 Log.e(TAG, "getFromLocationName: got RemoteException", e);
184 return null;
185 }
186 }
187
188 /**
189 * Returns an array of Addresses that are known to describe the
190 * named location, which may be a place name such as "Dalvik,
191 * Iceland", an address such as "1600 Amphitheatre Parkway,
192 * Mountain View, CA", an airport code such as "SFO", etc.. The
193 * returned addresses will be localized for the locale provided to
194 * this class's constructor.
195 *
196 * <p> You may specify a bounding box for the search results by including
197 * the Latitude and Longitude of the Lower Left point and Upper Right
198 * point of the box.
199 *
200 * <p> The query will block and returned values will be obtained by means of a network lookup.
201 * The results are a best guess and are not guaranteed to be meaningful or
202 * correct. It may be useful to call this method from a thread separate from your
203 * primary UI thread.
204 *
205 * @param locationName a user-supplied description of a location
206 * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
207 * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box
208 * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box
209 * @param upperRightLatitude the latitude of the upper right corner of the bounding box
210 * @param upperRightLongitude the longitude of the upper right corner of the bounding box
211 *
212 * @return a list of Address objects. Returns null or empty list if no matches were
213 * found or there is no backend service available.
214 *
215 * @throws IllegalArgumentException if locationName is null
216 * @throws IllegalArgumentException if any latitude is
217 * less than -90 or greater than 90
218 * @throws IllegalArgumentException if any longitude is
219 * less than -180 or greater than 180
220 * @throws IOException if the network is unavailable or any other
221 * I/O problem occurs
222 */
223 public List<Address> getFromLocationName(String locationName, int maxResults,
224 double lowerLeftLatitude, double lowerLeftLongitude,
225 double upperRightLatitude, double upperRightLongitude) throws IOException {
226 if (locationName == null) {
227 throw new IllegalArgumentException("locationName == null");
228 }
229 if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
230 throw new IllegalArgumentException("lowerLeftLatitude == "
231 + lowerLeftLatitude);
232 }
233 if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
234 throw new IllegalArgumentException("lowerLeftLongitude == "
235 + lowerLeftLongitude);
236 }
237 if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
238 throw new IllegalArgumentException("upperRightLatitude == "
239 + upperRightLatitude);
240 }
241 if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
242 throw new IllegalArgumentException("upperRightLongitude == "
243 + upperRightLongitude);
244 }
245 try {
246 ArrayList<Address> result = new ArrayList<Address>();
247 String ex = mService.getFromLocationName(locationName,
248 lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
249 maxResults, mParams, result);
250 if (ex != null) {
251 throw new IOException(ex);
252 } else {
253 return result;
254 }
255 } catch (RemoteException e) {
256 Log.e(TAG, "getFromLocationName: got RemoteException", e);
257 return null;
258 }
259 }
260}