1 package com.xtremelabs.robolectric.shadows; 2 3 import android.location.Address; 4 import android.location.Geocoder; 5 import com.xtremelabs.robolectric.internal.Implementation; 6 import com.xtremelabs.robolectric.internal.Implements; 7 8 import java.io.IOException; 9 import java.util.ArrayList; 10 import java.util.List; 11 import java.util.Locale; 12 13 import static com.xtremelabs.robolectric.Robolectric.shadowOf; 14 15 /** 16 * A shadow for Geocoder that supports simulated responses and failures 17 */ 18 @SuppressWarnings({"UnusedDeclaration"}) 19 @Implements(Geocoder.class) 20 public class ShadowGeocoder { 21 private String addressLine1; 22 private String city; 23 private String state; 24 private String zip; 25 private String countryCode; 26 private boolean wasCalled; 27 private double lastLatitude; 28 private double lastLongitude; 29 private String lastLocationName; 30 private double simulatedLatitude; 31 private double simulatedLongitude; 32 private boolean shouldSimulateGeocodeException; 33 private boolean hasLatitude; 34 private boolean hasLongitude; 35 private boolean returnNoResults = false; 36 private boolean didResolution; 37 38 @Implementation getFromLocation(double latitude, double longitude, int maxResults)39 public List<Address> getFromLocation(double latitude, double longitude, int maxResults) throws IOException { 40 wasCalled = true; 41 this.lastLatitude = latitude; 42 this.lastLongitude = longitude; 43 if (shouldSimulateGeocodeException) { 44 throw new IOException("Simulated geocode exception"); 45 } 46 Address address = makeAddress(); 47 address.setAddressLine(0, addressLine1); 48 address.setLocality(city); 49 address.setAdminArea(state); 50 address.setPostalCode(zip); 51 address.setCountryCode(countryCode); 52 return oneElementList(address); 53 } 54 55 @Implementation getFromLocationName(String locationName, int maxResults)56 public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException { 57 didResolution = true; 58 this.lastLocationName = locationName; 59 if (shouldSimulateGeocodeException) { 60 throw new IOException("Simulated geocode exception"); 61 } 62 if (returnNoResults) { 63 return new ArrayList<Address>(); 64 } else { 65 Address address = makeAddress(); 66 address.setLatitude(simulatedLatitude); 67 address.setLongitude(simulatedLongitude); 68 return oneElementList(address); 69 } 70 } 71 makeAddress()72 private Address makeAddress() { 73 Address address = new Address(Locale.getDefault()); 74 shadowOf(address).setSimulatedHasLatLong(hasLatitude, hasLongitude); 75 return address; 76 } 77 78 /** 79 * Sets up a simulated response for {@link #getFromLocation(double, double, int)} 80 * 81 * @param address the address for the response 82 * @param city the city for the response 83 * @param state the state for the response 84 * @param zip the zip code for the response 85 * @param countryCode the country code for the response 86 */ setSimulatedResponse(String address, String city, String state, String zip, String countryCode)87 public void setSimulatedResponse(String address, String city, String state, String zip, String countryCode) { 88 this.addressLine1 = address; 89 this.city = city; 90 this.state = state; 91 this.zip = zip; 92 this.countryCode = countryCode; 93 } 94 95 96 /** 97 * Sets up a simulated response for {@link #getFromLocationName(String, int)}} 98 * 99 * @param lat latitude for simulated response 100 * @param lng longitude for simulated response 101 */ setSimulatedLatLong(double lat, double lng)102 public void setSimulatedLatLong(double lat, double lng) { 103 this.simulatedLatitude = lat; 104 this.simulatedLongitude = lng; 105 } 106 107 /** 108 * Sets a flag to indicate whether or not {@link #getFromLocationName(String, int)} should throw an exception to 109 * simulate a failure. 110 * 111 * @param shouldSimulateException whether or not an exception should be thrown from {@link #getFromLocationName(String, int)} 112 */ setShouldSimulateGeocodeException(boolean shouldSimulateException)113 public void setShouldSimulateGeocodeException(boolean shouldSimulateException) { 114 this.shouldSimulateGeocodeException = true; 115 } 116 117 /** 118 * Non-Android accessor that indicates whether {@link #getFromLocation(double, double, int)} was called. 119 * 120 * @return whether {@link #getFromLocation(double, double, int)} was called. 121 */ wasGetFromLocationCalled()122 public boolean wasGetFromLocationCalled() { 123 return wasCalled; 124 } 125 getLastLongitude()126 public double getLastLongitude() { 127 return lastLongitude; 128 } 129 getLastLatitude()130 public double getLastLatitude() { 131 return lastLatitude; 132 } 133 getLastLocationName()134 public String getLastLocationName() { 135 return lastLocationName; 136 } 137 oneElementList(Address address)138 private List<Address> oneElementList(Address address) { 139 ArrayList<Address> addresses = new ArrayList<Address>(); 140 addresses.add(address); 141 return addresses; 142 } 143 setSimulatedHasLatLong(boolean hasLatitude, boolean hasLongitude)144 public void setSimulatedHasLatLong(boolean hasLatitude, boolean hasLongitude) { 145 this.hasLatitude = hasLatitude; 146 this.hasLongitude = hasLongitude; 147 } 148 setReturnNoResults(boolean returnNoResults)149 public void setReturnNoResults(boolean returnNoResults) { 150 this.returnNoResults = returnNoResults; 151 } 152 didResolution()153 public boolean didResolution() { 154 return didResolution; 155 } 156 }