package org.microg.networklocation.platform; import android.location.Address; import android.location.GeocoderParams; import android.util.Log; import org.microg.networklocation.MainService; import org.microg.networklocation.database.GeocodeDatabase; import org.microg.networklocation.source.GeocodeSource; import java.util.ArrayList; import java.util.List; class GeocodeProvider extends internal.com.android.location.provider.GeocodeProvider implements org.microg.networklocation.provider.GeocodeProvider { private static final String TAG = "nlp.LocationGeocodeProvider"; private static final String UNKNOWN_RESULT_ERROR = "unknown"; private GeocodeDatabase geocodeDatabase; private List<GeocodeSource> sources; @Override public void setGeocodeDatabase(GeocodeDatabase geocodeDatabase) { this.geocodeDatabase = geocodeDatabase; } @Override public String onGetFromLocation(double latitude, double longitude, int maxResults, GeocoderParams params, List<Address> addrs) { if (MainService.DEBUG) { Log.d(TAG, "Reverse request: " + latitude + "/" + longitude); } List<Address> addresses = null; if (geocodeDatabase != null) { addresses = geocodeDatabase.get(latitude, longitude); } if ((addresses != null) && !addresses.isEmpty()) { // database hit if (MainService.DEBUG) { Log.d(TAG, "Using database entry: " + addrs.get(0)); } addrs.addAll(addresses); return null; } for (GeocodeSource source : sources) { if (source.isSourceAvailable()) { if (MainService.DEBUG) { Log.d(TAG, "Try reverse using: " + source.getName()); } try { addresses = source.getFromLocation(latitude, longitude, params.getClientPackage(), params.getLocale()); } catch (Throwable t) { Log.w(TAG, source.getName() + " throws exception!", t); } if ((addresses != null) && !addresses.isEmpty()) { geocodeDatabase.put(latitude, longitude, addresses); addrs.addAll(addresses); if (MainService.DEBUG) { Log.d(TAG, latitude + "/" + longitude + " reverse geolocated to:" + addrs.get(0)); } return null; // null means everything is ok! } } } if (MainService.DEBUG) { Log.d(TAG, "Could not reverse geolocate: " + latitude + "/" + longitude); } return UNKNOWN_RESULT_ERROR; } @Override public String onGetFromLocationName(String locationName, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude, int maxResults, GeocoderParams params, List<Address> addrs) { if (MainService.DEBUG) { Log.d(TAG, "Forward request: " + locationName); } List<Address> addresses = geocodeDatabase.get(locationName); if ((addresses != null) && !addresses.isEmpty()) { // database hit addrs.addAll(addresses); return null; } for (GeocodeSource source : sources) { if (source.isSourceAvailable()) { try { addresses = source.getFromLocationName(locationName, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude, params.getClientPackage(), params.getLocale()); } catch (Throwable t) { Log.w(TAG, source.getName() + " throws exception!", t); } if ((addresses != null) && !addresses.isEmpty()) { geocodeDatabase.put(locationName, addresses); addrs.addAll(addresses); if (MainService.DEBUG) { Log.d(TAG, locationName + " forward geolocated to:" + addrs.get(0)); } return null; // null means everything is ok! } } } if (MainService.DEBUG) { Log.d(TAG, "Could not forward geolocate: " + locationName); } return UNKNOWN_RESULT_ERROR; } public void setSources(List<GeocodeSource> sources) { this.sources = new ArrayList<GeocodeSource>(sources); } }