1 /* 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 17 package android.location; 18 19 import android.content.Context; 20 import android.location.Address; 21 import android.os.RemoteException; 22 import android.os.IBinder; 23 import android.os.ServiceManager; 24 import android.util.Log; 25 26 import java.io.IOException; 27 import java.util.Locale; 28 import java.util.ArrayList; 29 import 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 */ 47 public 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 */ isPresent()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 */ Geocoder(Context context, Locale locale)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 */ Geocoder(Context context)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 */ getFromLocation(double latitude, double longitude, int maxResults)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 */ getFromLocationName(String locationName, int maxResults)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 */ getFromLocationName(String locationName, int maxResults, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude)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 } 261